1 对 1 关系的性能更好:新表或 VARCHAR 列有很多空条目

Posted

技术标签:

【中文标题】1 对 1 关系的性能更好:新表或 VARCHAR 列有很多空条目【英文标题】:What is better in performance for 1-to-1 relationship: a new table or a VARCHAR column with a lot of empty entries 【发布时间】:2017-06-11 17:13:03 【问题描述】:

我必须决定是向现有表添加新列 (VARCHAR) 还是创建新表。

如果添加了一个新列,则会有空条目,所以我想知道当数据类型为 VARCHAR 时这有多有害。

所以具体来说,我有一个“消息”表,我在其中存储从 userA 到 userB 的消息。每个用户都应该有机会准确地响应给定消息 1 次,因此我可以将带有 VARCHAR 的“响应”列添加到现有消息表中,或者我可以创建一个带有“index_message”和“响应”的新表“响应”作为列。

什么更好?

编辑:

创建表`消息`(
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `sender` int(10) unsigned NOT NULL,
  `receiver` int(10) unsigned NOT NULL,
  `message` varchar(150) 整理 utf8_unicode_ci DEFAULT NULL,
  `ref` varchar(180) 整理 utf8_unicode_ci DEFAULT NULL,
  `status` tinyint(4) NOT NULL DEFAULT '0',
  `type` tinyint(4) NOT NULL,
  `multiple` tinyint(4) NOT NULL DEFAULT '0',
  `timestamp` int(11) NOT NULL,
  主键(`id`)
) 引擎=InnoDB AUTO_INCREMENT=82 默认字符集=utf8 COLLATE=utf8_unicode_ci;
CREATE TABLE `responses` (
  `msg_id` int(10) 无符号非空,
  `response` varchar(140) 整理 utf8_unicode_ci NOT NULL,
  主键(`msg_id`)
) 引擎=InnoDB 默认字符集=utf8 排序=utf8_unicode_ci;

【问题讨论】:

具体是当你分享一些实际的表格时 这是 Stack Overflow 以友好和热情的语气而闻名的另一个很好的例子吗,@e4c5? (但是,是的,OP,你绝对应该分享你的表结构。) 在这种特定情况下,我会选择该列:检索数据时它会更快,因为您不必进行连接。使用单独的表可以节省微不足道的磁盘空间,但我认为这不是问题。 @Pekka웃 我补充了缺失的信息,谢谢你不要粗鲁。 是的,在您拥有数百万或数十亿条记录之前,性能不太可能成为问题。规范化的方法可能会使未来的变化更容易——但也会增加很多复杂性。我也会选择专栏 【参考方案1】:

这完全取决于您的需求或流程。

如果您允许用户对消息只回复一次,那么只选择 1 个表格。

CREATE TABLE `messages` (
  columns go here.....
) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

如果您允许用户对一条消息多次回复,因为可能会发生跟进,那么请使用多表关系。

CREATE TABLE `messages` (
  columns go here...
) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

CREATE TABLE `responses` (
  msg_id, response, sender....
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

但您也可以允许您的用户对仅使用 1 个表格的消息进行多次回复。您只需将msg_id column 放在messages table 中,因此每条消息和回复都保存在同一个表中。通过该设置,用户可以回复消息和回复(就像电子邮件的工作方式一样,但我并不是说他们使用相同的表结构)。

CREATE TABLE `messages` (
  id, title, to, from, message/response, date, msg_id....
) ENGINE=InnoDB AUTO_INCREMENT=82 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

【讨论】:

【参考方案2】:

使用两个表和连接将使您的查询时间翻倍。当涉及到 1-1 关系时,您应该始终合并两个表。

唯一的缺点是缺乏灵活性。假设您决定将来允许多次回复,您将不得不做很多更改。这就是为什么在项目结束时进行这种优化的原因。

如果您使用 ORM(如 hibernate),您可以选择是否应将数据存储在一个或两个表中,而不会影响您的查询。

【讨论】:

以上是关于1 对 1 关系的性能更好:新表或 VARCHAR 列有很多空条目的主要内容,如果未能解决你的问题,请参考以下文章

数据库:订单属性的新表或新字段

CSV 文件到 Lua 表并作为新表或函数访问这些行()

多对多关系:使用数组或创建新表[重复]

mysql 优化表或新建一个

存储用户并传入单个表或单独的表

ORA-00942: 表或视图不存在解决方法