【问题标题】:mysql - store typically/mostly NULL columns in one table or create 1:1 relationship?mysql - 在一个表中存储通常/大部分为 NULL 列或创建 1:1 关系?
【发布时间】:2019-09-19 04:34:50
【问题描述】:

运行Mysql Server版本:5.7.27-0ubuntu0.18.04.1

我正在创建一个网站/应用程序,其中用户“提交”可以是以下之一:

  1. 文字评论
  2. 图片/文件上传
  3. 视频/文件上传(技术上与 #2 大致相同,只是 MIME 类型不同)

我在两种设计之间做出选择时遇到了麻烦(为简洁起见缩短了)...

CREATE TABLE submissions
(
    submissionID            INT,
    userID                  INT,
    submissionComments      TEXT,
    fileDirectory           VARCHAR2(32), -- starting here these are only used 20% of time
    fileName                VARCHAR2(128)
    fileMimeType            VARCHAR2(128),
    fileSize                INT,
    originalFileName        VARCHAR2(64)
)

-或-

CREATE TABLE submissions
(
    submissionID            INT,
    userID                  INT,
    submissionComments      TEXT
)

CREATE TABLE submissionFiles
(
    submissionFileID        INT,
    submissionID            INT, -- FK to submissions table
    fileDirectory           VARCHAR2(32),
    fileName                VARCHAR2(128),
    fileMimeType            VARCHAR2(128),
    fileSize                INT,
    originalFileName        VARCHAR2(64)    
)

我假设文本 cmets 可能占提交的 70-80%。

所以,问题变成了,使用单个表并在 fileDirectory/fileName/fileMimeType/fileSize/originalFileName 中有一堆 NULL 值会更好吗? 或者,在上传文件时支持 1:1 关系是否更好。在这种情况下,我将同时创建提交和提交文件记录。显然大多数查询都需要连接这两个表。

这基本上归结为没有很好地理解 VARCHAR(和 1 个 INT)列在大多数为 NULL 的表中的影响。考虑到这是一个全新的网站/应用程序,我可能在这里进行了一些预优化,但我正在尝试提前计划。

后期添加的第二个问题(当我输入此问题时),我看到 TEXT 能够处理:65,535 个字符或 64 KB。对于典型用户提交的内容(可能少于 500 个字符)来说,这似乎很多。它会很快耗尽存储空间。将 submitComments 放入 VARCHAR(500) 而不是 TEXT 会产生影响吗?我假设如果有的话,除了能够存储“更少”之外,没有负面的权衡。

谢谢!

编辑:正如 madhur 指出的那样,关于“设计模式”也有类似的问题/很好的答案。我更关心性能。大量 varchar 的存在是否会对数据存储/检索产生负面影响(通过弄乱 mysql 实现页面/范围/等的方式)?

【问题讨论】:

  • 图片/文件上传也会有cmets吗?如果是,请检查这些重复项:stackoverflow.com/questions/3579079/…stackoverflow.com/questions/190296/…stackoverflow.com/questions/57905620/…
  • 感谢您的参考,我同意它们非常相似。然而,他们似乎专注于设计模式,而不一定是性能。我想我更担心性能。换句话说,由于对页面/范围(数据存储和检索的方式)的影响,在 mysql 中有一堆 NULL 列是否会破坏性能。
  • 如果你的表是 InnoDB(它们应该是),你不需要太担心 NULL 的值。就个人而言,我更愿意避免使用NULL 列。因此,第二个用例更接近于此,并且在 b/w 过度规范化和非规范化方面进行了很好的权衡。
  • 除非提交可以包含多个文件,否则单表是可行的方法。单表将更容易实现+维护,并且比有两个表执行得更好。 NULL 列的空间要求可以忽略不计,因此两张表实际上没有任何好处(提交是现实生活中的一个实体)。您可能需要考虑向表中添加类型列,以便您的查询/应用程序直接知道它是否应该处理文本或文件。

标签: mysql database-design


【解决方案1】:

无论哪种方式,我都构建了模式。在某种程度上,这并不重要。但是您可能会发现某些查询以一种方式(或另一种方式)更快。磁盘使用情况大致相同。

您的第二个选项允许(并因此暗示)每个“提交”有多个“文件”。对于这样的“多:1”关系,您必须使用 2 个表。

另一方面,如果每个“提交”只能有一个“文件”,则不需要submissionFileID(我认为它是PRIMARY KEY??)而是使用@ 987654323@ 第二张桌子。

如果您想进一步讨论,请提供完整的CREATE TABLE,包括NULLNOT NULL,每个表的PRIMARY KEY,以及任何二级索引。

将评论提交到 VARCHAR(500) 而不是 TEXT?

  • 没有存储差异。
  • 没有速度差异。
  • 前者会在 500 个字符处截断,给出警告或错误;后者将在 65535 字节处截断。我会简单地使用TEXT

回到主要问题。您的示例有几列全部为 NULL 或全部填充。因此,我倾向于 2 个表。

【讨论】:

    猜你喜欢
    • 2020-09-02
    • 2013-09-03
    • 1970-01-01
    • 2020-05-26
    • 2018-08-02
    • 2011-12-14
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    相关资源
    最近更新 更多