服务器同步db应用程序,主键问题,多表,节省存储空间

rwqw0loc  于 2021-06-19  发布在  Mysql
关注(0)|答案(1)|浏览(241)

我计划制作一个应用程序,可以选择在mysql中央服务器(云)上存储数据条目,并使用该服务器备份数据条目或在不同设备之间同步数据条目。
现在,我非常粗糙的表格布局如下所示:

服务器的用户表

用户id(int主键自动递增)
last\u update—上一次更新任何数据项的时间戳
电子邮件
密码-加盐和哈希

服务器的数据输入表

服务器\u条目\u id(int主键自动递增)-在所有设备上都是唯一的
用户id(int)-来自服务器的用户表
上次更新-上次更新此数据项的时间戳
实际数据列。。。

客户端应用程序数据输入表

行\u id(int主键自动递增)-仅用于本地应用程序数据库操作,不共享
服务器\条目\标识(int)-这是添加到服务器时从服务器检索到的唯一服务器数据条目标识
上次更新-此数据项上次在应用程序中本地的时间戳
实际数据列。。。

问题

我的问题其实不是关于同步逻辑。如果我有大量的用户和数据输入,我希望尽可能提前计划以避免潜在的问题。
可以使用int autoincrement主键(pk)来获取有用的信息,比如用户id或数据条目id吗?我听说这不是一个好的做法,但我也看到过pk用于获取有用信息的例子。是否担心在需要时很难将行迁移到不同的表或数据库中?服务器上的服务器\u条目\u id与与与该服务器同步的所有设备上的服务器\u条目\u id相同。另一种方法是使用uuid作为服务器条目,但是它们不是自动递增的,所以我认为搜索速度会慢一些,而且会占用更多的db空间(16字节blob)。
如果服务器上的数据输入表可能变得非常大,那么制作多个数据输入表是一个好主意吗?例如,用户id 0-9999可以使用表1,用户id 10000-19999可以使用表2,等等。同样,将用户的数据保存在一个表中会使检索单个用户的所有数据比检索单独的表更快。
假设我有一个数据输入表,其中有5个int列和3个double列用于存储实际数据。我们还可以说,这8列只需要在一起,并且在mysql查询的where子句中永远不会搜索到。假设这8列的值通常为0。因为mysql使用相同的存储空间来存储int 0和2147483647,所以最好使用类似的存储模式将这8列存储为字节blobhttps://www.sqlite.org/fileformat2.html#varint?

enxuqcxy

enxuqcxy1#

一个表中的行数没有截断。随着table越来越大,问题也越来越多。百行表工作正常,没有规范化和索引;十亿行表需要这两种数据类型,再加上不断缩小的数据类型。等等(在一项调查中,50米排大约是第96个百分点。我在一张表中看到了超过十亿行。)
uuid对于大型表的性能很差;尽量避开他们(是的,把它们装进 BINARY(16) 比…好 VARCHAR(36) .
我有三分之二的table不用 AUTO_INCREMENT ; 相反,他们有一个“自然”的pk。所以,很明显,我说“这取决于”当谈到pks。userid最好是用 SMALLINT UNSIGNED 或者 MEDIUMINT UNSIGNED ,这取决于您预期的用户数是不超过64k还是1600万。很少有人需要 INT ,更不用说了 BIGINT . (它们的大小分别为2、3、4、8字节。)
不可接受的缺点- AUTO_INCREMENT pk是将pk的一个副本连接到每个次键,从而添加到它们的块中。但是,粗略地说:
大pk,但没有副键:好
大pk和一个辅助密钥:使用或不使用ai占用大约相同的磁盘空间。
大pk和多个辅助键:ai开始闪耀(空间方面)。
不要将一张大table拆分成多张小table。麻烦是巨大的,利益是微乎其微的。甚至 PARTITIONing 不太可能提供任何好处。
“规范化”具有重复值的大型ish列通常是一个好主意(节省空间 JOIN 把东西重新组装起来也不错。)
有这8列的50m行加起来可能达到4gb左右。这不是很大。这不值得玩 BLOB 同时,考虑使用比4字节更小的整数类型 INT ; 考虑 UNSIGNED ; 考虑 FLOAT 对决加倍。 mysql中没有“varint”的等价物。 评论http://www.agiledata.org/essays/keys.html : “key”不一定唯一地标识一行。“备用钥匙”同上。关键字UNIQUE是需要的。 在mysql中PRIMARY KEY它的特殊之处在于它唯一地标识行,并与数据“聚集”在一起。 在mysql中,几乎总是首选使用它VARCHAR而不是CHAR. 在mysql中,AUTO_INCREMENT` 通常是“代理”键的首选技术。

相关问题