没有主键的 MySQL 表(最佳实践)

btx*_*btx 7 mysql database-design

我有一个users包含多个用户信息的表。我想将用户特定的权限存储在不同的表中。

我是否需要在表中拥有主键up_iduser_permissinos,即使它不会在任何地方使用?我知道总是建议在表中设置主键,但在这种情况下,这对我来说没有意义。如果我需要加入两个表,我将在 user_id 上加入 up_of_user。

Table `user`
==========================
user_id int(11) PK AI NN
user_name varchar(50)
...


Table `user_permissions`
=======================================
up_id int(11) PK AI NN
up_of_user int(11) FK of user.user_id
up_edit_post tinyint(4) DEFAULT '0'
Run Code Online (Sandbox Code Playgroud)

Noo*_*oob 6

请阅读MySQL的文档:

表的主键代表您在最重要的查询中使用的列或列集。它有一个关联索引,可实现快速查询性能。查询性能受益于 NOT NULL 优化,因为它不能包含任何 NULL 值。使用InnoDB存储引擎,表数据被物理组织以基于主键列进行超快速查找和排序。

如果您的表很大且很重要,但没有明显的列或一组列用作主键,您可以创建一个具有自动增量值的单独列用作主键。当您使用外键连接表时,这些唯一 ID 可以用作指向其他表中相应行的指针。

根据我的经验和知识,如果您不定义主键,数据库将创建一个隐藏的主键。在你的情况下我应该保留主键。

感谢@AaronDigulla 的解释...:

必要的?不。在幕后使用?嗯,它被保存到磁盘并保存在行缓存等中。删除会稍微提高您的性能(使用具有毫秒精度的手表来注意)。

但是......下次有人需要创建对此表的引用时,他们会诅咒你。如果他们勇敢的话,他们会添加一个PK(并等待很长时间DB创建列)。如果他们不勇敢或不愚蠢,他们将开始使用业务密钥(即数据列)创建引用,这将导致维护噩梦。

结论:既然拥有一台PK(即使不使用ATM)的成本是如此之小,那就顺其自然吧。


Ric*_*mes 5

InnoDB有3种PK选择:按顺序,

  1. 明确PRIMARY KEY(...)——最佳实践:始终这样做。
  2. 第一个UNIQUE(...)包含所有NON NULL列。-- 比 #1 更马虎。
  3. 隐藏的 6 字节 ~ 整数。-- 由于它是隐藏式的,所以桌子上的维护很困难。

AUTO_INCREMENT与“自然”PK:

第一条规则:如果您有自然密钥,请使用它而不是添加人工 ID。我创建的大约 2/3 的表具有“自然”PK,有时是“复合”(多列)。

第二条规则:如果您有多个二级索引,则使用 AI PK 可能需要更少的空间。这是因为每个辅助密钥都包含 PK 的副本。

第三条规则:只有一个二级索引,这是一个折腾。

例子

老太太的故事又名“假新闻”

  • “庞大的 PK 很慢”——也许,也许不是。
  • “VARCHAR PK 很慢”——慢不了多少。

如果你还有其他积蓄(例如,去掉一根柱子),这可能会推翻老太太的故事。

你的例子

折腾up_id推广user_name做PK。

听起来和useruser_permissions1:1的关系?两张桌子的PK相同的情况是非常罕见的。通常应将两个表合并为一个表。