我从未选择过的MySQL主键

时间:2019-01-30 20:26:31

标签: mysql indexing database-design primary-key

我经常遇到这样的情况:

table `user_adress`
+----------+-------------+--------------+---------+
|adress_id | user_id     | adress_type  |adress   |
+----------+-------------+--------------+---------+
|        1 |           1 | home         |adressXXX|
|        2 |           2 | home         |adressXXX|
|        3 |           3 | home         |adressXXX|
|        4 |           1 | work         |adressXXX|
|        5 |           2 | work         |adressXXX|
|        6 |           1 | second_home  |adressXXX|
+----------+-------------+--------------+---------+

如果我想使用它,我正在使用如下查询:

SELECT `adress` FROM `user_adress` WHERE `user_id`=1;

看起来很正常,但事实是,我使用了“无用的” adress_id列,它没有其他用途,而是为了自动增加主键,只是为了在MySQL表中拥有主键。我从不使用或不需要此号码。因此,我发现我根本不应该在表中使用主键,而应完全删除adress_id,并在INDEX列中设置unique(无user_id)。看起来不错-还是我错了?

我有一些疑问,因为在我阅读的文章中,到处都有建议,每个表都应该甚至需要具有主键。但为什么?如果我允许这种情况发生,也许我的数据库设计不佳,但是看着我极其简单的示例表-我无法想象在每种情况下都可能出现这种情况,尤其是在这种简单情况下。我明确地误解了一些有关创建表并正确索引它们的简单基本规则-我的难题在哪里?

3 个答案:

答案 0 :(得分:1)

从您的数据中可以明显看出,主键允许直接访问单行而没有任何问题或歧义..(尤其是删除或更新)

这是主键的专门用途。

事实上您可能需要通过user_id将此表与其他表连接

和user_id上的索引(不是唯一的)

create index  myidx on mytable(user_id)

对于加快连接速度非常有用,它只允许在与单个user_id相关的行上直接访问

答案 1 :(得分:1)

完全基于您的表结构,我会说您的主键不正确。

相反,您的主要对象应该是:

PRIMARY KEY (user_id, address_type)

您是正确的,每个表在理想情况下都应具有主键,但是主键可以覆盖多个字段。

使用简单的自动递增ID作为主键有时仍然更容易。 Innodb存储引擎实际上将在不可见的字段中秘密地执行此操作。

也许在您的有限示例中,它不是必需的,但在许多实际情况下,它可以使处理数据更加容易。从这种意义上讲,我要说的是,从学术的角度来看,拥有人工自动递增的主键不是最佳实践,但是从“现实世界,操作和MySQL管理员”的角度来看,这可能是个好主意。

还有一些仅要求此的ORM系统(就那样不好)。

答案 2 :(得分:1)

关系数据库表确实需要一个主键。

但这全都归结为主键的定义。主键不一定是自动递增的单个整数列。

主键是可以唯一标识每一行的任何列或一组多列。在您的情况下,user_idaddress_type的组合可以做到这一点(如Evert已发布)。

因此,如果您像这样制作表格:

CREATE TABLE user_address (
  user_id INT NOT NULL,
  address_type varchar(10) NOT NULL,
  address TEXT NOT NULL,
  PRIMARY KEY (user_id, address_type)
);

然后您可以一次更新或删除一个特定行:

UPDATE user_address SET ...
WHERE user_id = ? AND address_type = ?;

有些人认为,强制执行约定(每个表都应具有单个整数列作为其主键)更为方便。他们甚至可能坚持认为,为了保持一致性,必须将列命名为id

在一致性方面有一些优势,但是另一方面,即使没有帮助,坚持这种约定也有点不明智。