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))

总的来说,我只想知道如何解决这个问题。

如果您在欧盟有数据驻留要求,那么您要么需要两台服务器,要么需要将所有数据存储在欧盟。

如果您对数据进行分片(将其拆分到多个服务器),那么唯一键通常会有些复杂。

至少有四种流行的生成全局唯一 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/ 等文章(尽管该文章不是法律建议),在某些情况下,您不需要这样做。