服务器同步数据库应用,主键问题,多个表和节省存储空间

时间:2018-10-22 17:41:48

标签: mysql database database-design primary-key

我计划开发一个可以选择性地将数据条目存储在mysql中央服务器(云)上的应用程序,并将该服务器用作备份数据条目或在不同设备之间同步数据条目的一种方式。

现在,我非常粗糙的表布局看起来像这样:


服务器的USER表

  • USER_ID(INT主键自动增加)
  • LAST_UPDATE-上一次更新任何数据条目的时间戳
  • 电子邮件
  • 密码-加盐和散列

服务器的数据输入表

  • SERVER_ENTRY_ID(INT主键自动增加)-在所有设备上都是唯一的
  • USER_ID(INT)-来自服务器的用户表
  • LAST_UPDATE-上次更新此数据条目的时间戳
  • Columns_For_Actual_Data ...

客户端应用数据输入表

  • ROW_ID(INT主键自动增加)-仅用于本地应用程序数据库操作,不共享
  • SERVER_ENTRY_ID(INT)-这是添加到服务器时从服务器检索的唯一服务器数据条目ID
  • LAST_UPDATE-上一次此数据输入位于应用程序本地的时间戳
  • Columns_For_Actual_Data ...

问题

我的问题实际上与同步逻辑无关。如果要获得大量的用户和数据输入,我想尽可能地提前计划以避免潜在的问题。

  1. 是否可以将INT自动增量主键(PK)用于有用的信息,例如UserID或Data-Entry-ID?我听说这不是一个好习惯,但是我也看到了一些示例,其中PK用于提供有用的信息。是否担心是否需要将行迁移到不同的表或数据库中?服务器上的SERVER_ENTRY_ID与与该服务器同步的所有设备上的SERVER_ENTRY_ID相同。另一种想法是对SERVER_ENTRY_ID使用UUID,但是它们不会自动递增,因此我认为搜索速度会变慢,并且会占用更多的数据库空间(16字节Blob)。

  2. 如果服务器上的数据输入表可能变得非常大,那么改用多个数据输入表是个好主意吗?例如,user_id 0-9999可以使用Table1,user_id 10000-19999可以使用Table2,等等。另外,将用户的数据全部保存在一个表中将使单个用户的所有数据检索比单独的表更快。 li>

  3. 假设我有一个数据输入表,其中包含5个INT列和3个DOUBLE列,用于存储实际数据。还可以说这8列仅一起需要,并且永远不会在带有MYSQL查询的WHERE子句中搜索。我们还要说,这8列的值通常为0。由于MySql使用相同数量的存储空间来存储INT的0和2,147,483,647,是否最好使用https://www.sqlite.org/fileformat2.html#varint之类的存储模式将这8列存储为字节blob?

1 个答案:

答案 0 :(得分:0)

一张表中的行数没有中断。随着桌子变大,出现了越来越多的问题。一百行的表在没有规范和索引的情况下工作正常;十亿行表既需要又需要缩小的数据类型。等等。(在一项调查中,5000万行约占第96个百分位数。我在一个表中看到的行数超过10亿。)

UUID占用大量表的性能;尽量避免它们。 (是的,将它们打包到BINARY(16)中比VARCHAR(36)好。

my 表中的

2/3不使用AUTO_INCREMENT;相反,它们具有“自然” PK。因此,很明显,对于PK,我说“取决于”。最好使用SMALLINT UNSIGNEDMEDIUMINT UNSIGNED来完成UserID,这取决于您希望不超过64K或1600万用户。很少需要INT,更不用说BIGINT。 (它们的大小分别为2、3、4、8个字节。)

AUTO_INCREMENT PK的一个缺点是PK的副本连接到每个辅助密钥,从而增加了它们的容量。但是,粗略地说:

  • 大PK,但没有辅助键:很好
  • 大PK和一个辅助键:带有或不带有AI的磁盘空间大约相同。
  • 大PK和多个辅助键:AI开始发光(在空间方面)。

不要将一个大表拆分为多个较小的表。麻烦很大,收益却很小。甚至PARTITIONing也不太可能提供任何好处。

用重复的值“标准化”大的列通常是一个好主意。 (虽然节省了空间,但是JOIN可以将它们放回原处也不错。)

具有这8列的5000万行可能总计约4GB。这不是很大。它不保证可以玩BLOB游戏(除非应用程序代码真的这样喜欢)。同时,请考虑小于4字节INT的整数类型;考虑UNSIGNED;考虑将FLOAT与“ DOUBLE”相对应。

MySQL中没有等效的'varint'。

http://www.agiledata.org/essays/keys.html的评论:

  • “键”不一定唯一标识行。同上“辅助密钥”。关键字UNIQUE是必需的。
  • 在MySQL中,PRIMARY KEY的特殊之处在于它唯一地标识行并与数据“聚集”。
  • 在MySQL中,几乎总是首选使用VARCHAR而不是CHAR
  • 在MySQL中,AUTO_INCREMENT通常是“代理”键的首选技术。