【发布时间】:2019-12-04 08:20:12
【问题描述】:
这只是一个概括的例子。我有一个包含几十行数据的静态 MySQL 数据库参考表。该表的结构如下所示:
video_games
id int(11)
release_date datetime
title varchar(64)
msrp float
我有一个名为“users”的单独表,其中包含一个“favorite_video_game_id”列,该列可以指向“video_games”中的“id”列。
在我建立的一个网站上,我有一个特殊页面,专门用于显示几个特定游戏(“守望先锋”、“魔兽争霸”和“暗黑破坏神”)粉丝的用户名。为了拉回游戏信息和喜欢的用户,我有一个类似下面的mysql语句:
select u.*, vg.*
from users u, video_games vg
where u.favorite_video_game_id = vg.id and vg.title= 'Warcraft';
在某个时候,我意识到我想在数据库中为游戏命名一个更具体的名称,“魔兽世界”,因此我更新了数据库中的名称。然而,当我回到我的页面时,我意识到游戏信息和信息列表显示为空,因为“标题”列已更改,我现在需要更新我的所有代码。
当我意识到我想要扩展为更完整的名称的所有标题,以及我需要在网站上进行的所有代码更改时,我觉得我的 PHP 代码与 SQL 紧密耦合数据,就像我将内容数据硬编码到我的 PHP 文件中一样。我的第一个想法是更改 mysql 代码以直接引用 ID,如下所示:
select u.*, vg.*
from users u, video_games vg
where u.favorite_video_game_id = vg.id and vg.id= 13;
但是,我了解到不鼓励像这样直接使用主键列,因为将来可能会出现必须更改 id 或将数据传输到另一个数据库供应商的情况,并且 id 会不再正确。
我的下一个想法是添加另一个索引键列,可能是随机哈希值,这也是视频游戏独有的,不会遇到上述问题。但是当已经有 id 列时添加另一个唯一键列似乎有点奇怪/冗余,我想知道我是否可能会丢失/忽略一些东西,只要不将我的 PHP 耦合到内容列中的唯一标识行数据库。
在这种情况下,最佳设计实践是什么?谢谢。
【问题讨论】:
-
只是好奇,您从哪里读到不鼓励使用主键列?以前从未听说过这个,我想找出它这么说的原因。
-
无论是 ID 还是电影标题,数据都可能发生变化(无论风险多么小)。我想说在你不知道的情况下更改 ID 的风险相当小,因为这会严重限制典型关系数据库的可靠性。如果表格被视为静态,则标题更改的风险可能同样小。如果您必须对引用条目的值进行硬编码,我可能会将它们更新为新标题,特别是如果这只是一次性更改。
-
话虽如此,如果您担心 ID 发生变化(例如,您可能会更改数据库引擎或使用分布式环境),您可以使用服务器生成的 ID 而不是数据库 -生成的 ID。见Why Did We Shift Away From Database-Generated Ids?
-
@catcon 这是我在从事 Java 开发并在 Oracle RDBMS 工作时工作的一家大型(阅读:数百万美元的全球)咨询公司的标准经验法则。 TBH,自从我从事 PHP 开发以来,我一直对我从小公司的 Web 开发人员那里看到的一些数据库实践感到震惊,所以我试图在这里寻找最佳实践来处理这些问题耦合问题。
-
你也可以考虑问dba.stackexchange.com。
标签: php mysql database-design