LAd*_*das 1 performance foreign-key database-design table
我一直想知道以下方法是否不好或真的非常糟糕:)。
问题#1:我们可以使用和表indicator_id
中的数据进行合并(不使用)[我们知道我们可以,因为我们这样做了,但是它可以接受吗:)]?indicator_values
indicator_details
FOREIGN KEY
问题#2:如果我们决定使用indicator_id
(indicator_details
表中不是PK
),它会对性能产生重要影响吗?
正确理解 SQL 方法,最好的选择是在表中使用iid
( iid
as FOREIGN KEY
)indicator_values
而不是indicator_id
,但项目总是有一些限制(比如用户插入数据的方式 - 下面详细介绍),因此我们试图找到一个折衷的解决方案。
我知道这可能会导致数据完整性问题,但是没有 FK 的解决方案将非常用户友好(因为用户不必担心插入indicator_values
表中正确的行 - 具有正确的行iid
),特别是在我们的情况下,数据完整性是并不重要。此外,如果用户插入数据的唯一方法(在我们的例子中)是先从表中删除所有行,则使用 FK 的方法将导致在表更新ON DELETE
期间从指标值中删除所有行(由...引起)indicator_details
(再次 - 更新)意味着:删除所有行然后插入新数据),所以这会很耗时。
D B:
指标值表
+----------+--------------+------+-------+
| vid (PK) | indicator_id | year | value |
+----------+--------------+------+-------+
| 1 | AACA | 2001 | 10 |
| 2 | bbb | 2001 | 100 |
| 3 | ccc | 2001 | 10 |
| 4 | AACA | 2002 | 20 |
| 5 | bbb | 2002 | 200 |
| 6 | ccc | 2002 | 300 |
Run Code Online (Sandbox Code Playgroud)
指标详细信息表
+----------+--------------+------------------+-----------------------------+
| iid (PK) | indicator_id | desc | full_text |
+----------+--------------+------------------+-----------------------------+
| 1 | AACA | AACA is super | Lorem ipsum dolor sit amet |
| 2 | bbb | bbb is extra | Maecenas sagittis ultricies |
| 3 | ccc | ccc is superb | Praesent tincidunt nec orci |
Run Code Online (Sandbox Code Playgroud)
加入非 PK/FK 的列绝对没有问题。如果您关心效率,那么关键是定义适当的索引来支持您正在使用的连接操作。另外,不要假设外键的存在意味着索引的存在 - 有些数据库会自动创建这样的索引,但许多数据库不会自动创建这样的索引,因为它不是必需的,并且如果它永远不会真正帮助查询,则不必要地占用空间你跑。
主键和外键(以及唯一约束和其他数据库定义的限制)是出于数据完整性目的而存在的。
关于 FK 和ON DELETE CASCADE
人们删除父行:更安全的是不定义ON DELETE CASCADE
并在人们尝试时让它出错,而不是由于担心人为错误而不定义 FK 和其他数据完整性控制,因为这只会让自己在以后感到头痛。不应通过删除然后重新插入来更新行,这是导致此问题的行为,人们应该执行检查然后插入或根据需要更新或某种形式的UPSERT
操作(如果数据库支持) (MERGE
在某些系统中,例如 MS SQL Server,INSERT ... ON CONFLICT ...
或在其他系统中类似,等等)。