简体   繁体   English

不带主键的MySQL表(最佳实践)

[英]MySQL table without primary key (best practice)

I have a table users which contains several user information. 我有一个表users ,其中包含一些用户信息。 I'd like to store the user specific permissions in a different table. 我想将用户特定的权限存储在另一个表中。

Do I need to have the primary key up_id in the user_permissinos table, even if it will not be used anywhere? 即使在任何地方都不会使用,在user_permissinos表中是否需要主键up_id I know it is always recommended to have a primary key in a table, but in this case it makes no sense for me. 我知道总是建议在表中有一个主键,但是在这种情况下,这对我来说毫无意义。 If I need to join both tables I will join up_of_user on user_id. 如果需要连接两个表,我将在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'

Please read the documentation of MySQL: 请阅读MySQL的文档:

The primary key for a table represents the column or set of columns that you use in your most vital queries. 表的主键代表您在最重要的查询中使用的一列或一组列。 It has an associated index, for fast query performance. 它具有关联的索引,可提高查询性能。 Query performance benefits from the NOT NULL optimization, because it cannot include any NULL values. 查询性能得益于NOT NULL优化,因为它不能包含任何NULL值。 With the InnoDB storage engine, the table data is physically organized to do ultra-fast lookups and sorts based on the primary key column or columns. 使用InnoDB存储引擎,表数据在物理上进行了组织,以基于一个或多个主键列进行超快速查找和排序。

If your table is big and important, but does not have an obvious column or set of columns to use as a primary key, you might create a separate column with auto-increment values to use as the primary key. 如果您的表又大又重要,但是没有明显的列或一组列用作主键,则可以创建一个单独的列,并使用自动增量值作为主键。 These unique IDs can serve as pointers to corresponding rows in other tables when you join tables using foreign keys. 当您使用外键联接表时,这些唯一的ID可用作指向其他表中相应行的指针。

From my experience and knowledge if you do not define your primary key the database will create an hidden primary key. 根据我的经验和知识,如果您没有定义主键,数据库将创建一个隐藏的主键。 In your situation I should kept the primary key. 在您的情况下,我应该保留主键。

Thanks @AaronDigulla for his explanation...: 感谢@AaronDigulla的解释...:

Necessary? 必要? No. Used behind the scenes? 否。在幕后使用? Well, it's saved to disk and kept in the row cache, etc. Removing will slightly increase your performance (use a watch with millisecond precision to notice). 好了,它已经保存到磁盘上并保留在行缓存中,等等。删除将稍微提高您的性能(请使用毫秒级精度的手表来注意到)。

But ... the next time someone needs to create references to this table, they will curse you. 但是...下一次有人需要创建对此表的引用时,他们会诅咒您。 If they are brave, they will add a PK (and wait for a long time for the DB to create the column). 如果他们很勇敢,他们将添加一个PK(并等待很长时间让DB创建该列)。 If they are not brave or dumb, they will start creating references using the business key (ie the data columns) which will cause a maintenance nightmare. 如果他们不勇敢或愚蠢,他们将开始使用业务密钥(即数据列)创建引用,这将引起维护方面的噩梦。

Conclusion: Since the cost of having a PK (even if it's not used ATM) is so small, let it be. 结论:由于拥有PK的成本(即使未使用ATM的成本也是如此)很小,所以就顺其自然。

InnoDB has 3 choices of a PK: In order, InnoDB有PK的3种选择:

  1. Explicit PRIMARY KEY(...) -- Best practice: Always do this. 显式PRIMARY KEY(...) -最佳做法:始终这样做。
  2. The first UNIQUE(...) with all NON NULL columns. 具有所有NON NULL列的第一个UNIQUE(...) -- Sloppier than #1. -比#1笨拙。
  3. A hidden 6-byte ~integer. 一个隐藏的6字节〜integer。 -- Since it is hidden, it makes maintenance on the table difficult. -由于它是隐藏的,因此很难在桌子上进行维护。

AUTO_INCREMENT versus "natural" PK: AUTO_INCREMENT与“自然” PK:

First rule: If you have a natural key, use it rather than adding an artificial id. 第一条规则:如果您具有自然键,请使用它,而不要添加人工ID。 About 2/3 of the tables I have created have a "natural" PK, sometimes 'composite' (multiple columns). 我创建的表中约有2/3具有“自然” PK,有时是“复合”(多列)。

Second rule: If you have more than one secondary index, it may take less space to use an AI PK. 第二条规则:如果二级索引不止一个,则使用AI PK的空间可能会更少。 This is because every secondary key includes a copy of the PK. 这是因为每个辅助密钥都包含PK的副本。

Third rule: For only one secondary index, it is a toss up. 第三条规则:对于一个二级索引,它是一个折腾。

Examples 例子

Old wives' tales aka "Fake news" 老太太的故事又名“假新闻”

  • "A bulky PK is slow" -- maybe, maybe not. “庞大的PK速度很慢” –也许,也许不是。
  • "A VARCHAR PK is slow" -- not by much. “ VARCHAR PK速度很慢” –不会太大。

And if you have other savings (eg, getting rid of a column), that may override the old wives' tales. 而且,如果您还有其他积蓄(例如,摆脱专栏),那可能会取代老太太的故事。

Your example 你的例子

Toss up_id and promote user_name to be the PK. up_id并提升user_name为PK。

It sounds like user and user_permissions are in a 1:1 relationship? 听起来useruser_permissions是1:1关系? It is very rare to have two tables with the same PK. 具有相同PK的两个表非常少见 Normally the two tables should be combined into one. 通常,两个表应该合并为一个。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM