mysql 数据按地域分片
mysql data sharding geographically
数据按区域分片的常用方法是什么? a.k.a GDPR 执行 - 欧盟数据保留在欧盟。
如果我要在 users
table 中保存用户的 email
- 我需要以某种方式将美国和欧盟用户的数据分开。示例 mysql
table:
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
name VARCHAR(30),
email VARCHAR(30),
otherSensetiveData VARCHAR(30))
- 有 2 个服务器是否正常 - 1 个在欧盟,第二个在美国?
- 自动增量在这种情况下如何工作并加入selects/transactions?
总的来说,我只想知道如何解决这个问题。
如果您在欧盟有数据驻留要求,那么您要么需要两台服务器,要么需要将所有数据存储在欧盟。
如果您对数据进行分片(将其拆分到多个服务器),那么唯一键通常会有些复杂。
至少有四种流行的生成全局唯一 ID 值的解决方案:
使用自动递增,但要确保它们不会分配相同的 id 值,方法是使用 auto_increment_increment
设置为分片数量,auto_increment_offset
设置为不同的介于 0 和分片数量之间的值。例如,如果您有 2 个分片,auto_increment_increment
将在两个分片上设置为 2,并且 auto_increment_offset
将在美国分片上设置为 0,在欧盟分片上设置为 1。
使用复合主键,一列自增,另一列限制为不同的shardid。您可以在每个分片上以不同方式定义 table。
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
shardid INT NOT NULL CHECK (shardid = 1),
PRIMARY KEY(id, shardid)
);
不要使用MySQL内置的自增功能,而是创建一个全球唯一的id生成器服务,美国和欧盟的应用程序实例都调用它来获取下一个ID。这是客户端应用程序应该调用的东西,然后将值作为查询参数传递给 INSERT 语句。如果远程端在每次 INSERT 时调用此服务太慢,则远程应用程序可能会提前获取一批 id 值并将它们存储在本地,始终保持“供应”id 值以供使用。
使用 UUID 或全局唯一字符串。这部分由 MySQL 实例的服务器 ID 编码,因此它必然是唯一的。您可以在 MySQL 数据库中使用触发器来用 UUID 填充主键。
CREATE TRIGGER t BEFORE INSERT on users FOR EACH ROW SET id = UUID();
分片是一个复杂的主题,您需要选择最适合您应用的解决方案。
我建议您先与熟悉 GDPR 的合格法律专业人士交谈,以确认您确实有数据驻留要求。根据 https://www.mcafee.com/blogs/enterprise/data-security/data-residency-a-concept-not-found-in-the-gdpr/ 等文章(尽管该文章不是法律建议),在某些情况下,您不需要这样做。
数据按区域分片的常用方法是什么? a.k.a GDPR 执行 - 欧盟数据保留在欧盟。
如果我要在 users
table 中保存用户的 email
- 我需要以某种方式将美国和欧盟用户的数据分开。示例 mysql
table:
CREATE TABLE users(
id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY(id),
name VARCHAR(30),
email VARCHAR(30),
otherSensetiveData VARCHAR(30))
- 有 2 个服务器是否正常 - 1 个在欧盟,第二个在美国?
- 自动增量在这种情况下如何工作并加入selects/transactions?
总的来说,我只想知道如何解决这个问题。
如果您在欧盟有数据驻留要求,那么您要么需要两台服务器,要么需要将所有数据存储在欧盟。
如果您对数据进行分片(将其拆分到多个服务器),那么唯一键通常会有些复杂。
至少有四种流行的生成全局唯一 ID 值的解决方案:
使用自动递增,但要确保它们不会分配相同的 id 值,方法是使用
auto_increment_increment
设置为分片数量,auto_increment_offset
设置为不同的介于 0 和分片数量之间的值。例如,如果您有 2 个分片,auto_increment_increment
将在两个分片上设置为 2,并且auto_increment_offset
将在美国分片上设置为 0,在欧盟分片上设置为 1。使用复合主键,一列自增,另一列限制为不同的shardid。您可以在每个分片上以不同方式定义 table。
CREATE TABLE users( id INT NOT NULL AUTO_INCREMENT, shardid INT NOT NULL CHECK (shardid = 1), PRIMARY KEY(id, shardid) );
不要使用MySQL内置的自增功能,而是创建一个全球唯一的id生成器服务,美国和欧盟的应用程序实例都调用它来获取下一个ID。这是客户端应用程序应该调用的东西,然后将值作为查询参数传递给 INSERT 语句。如果远程端在每次 INSERT 时调用此服务太慢,则远程应用程序可能会提前获取一批 id 值并将它们存储在本地,始终保持“供应”id 值以供使用。
使用 UUID 或全局唯一字符串。这部分由 MySQL 实例的服务器 ID 编码,因此它必然是唯一的。您可以在 MySQL 数据库中使用触发器来用 UUID 填充主键。
CREATE TRIGGER t BEFORE INSERT on users FOR EACH ROW SET id = UUID();
分片是一个复杂的主题,您需要选择最适合您应用的解决方案。
我建议您先与熟悉 GDPR 的合格法律专业人士交谈,以确认您确实有数据驻留要求。根据 https://www.mcafee.com/blogs/enterprise/data-security/data-residency-a-concept-not-found-in-the-gdpr/ 等文章(尽管该文章不是法律建议),在某些情况下,您不需要这样做。