【问题标题】:When is it necessary to add a table in the database for lookup values何时需要在数据库中添加表以查找值
【发布时间】:2012-02-18 04:48:09
【问题描述】:
只是寻找一些关于何时使用查找值表的一般方向/最佳实践。假设我有一个包含交易/付款的表格,其中包含以下列:
交易
- transaction_id
- order_id
- amount_paid
- payment_status
- payment_type
好吧,假设 payment_type 可以是 3 个选项之一(“信用卡”、“直接信用”或“国际汇款”)。当前,对于每个表行,此 payment_type 字段都存储为文本。现在最好将此值存储为文本或为其创建一个查找表并将外键存储回事务表中?
例如
payment_type
- payment_type_id
- payment_type_name
交易
- transaction_id
- order_id
- amount_paid
- payment_status
- payment_type_id
现在我的想法是这个领域与 Web 应用程序紧密耦合,因此如果将来添加更多支付类型,应用程序可能必须进行更改以适应它。添加另一种付款类型就像文本一样容易,例如'paypal' 或在查找表中添加另一个条目。各种支付类型可以存储在一个数组中的网站代码中。
我可以看到使用查找表的好处是数据库中的整体数据更少(存储键而不是文本)。缺点可能是查询速度稍慢,因为它必须对数据进行另一次联接?
那么这里的最佳做法是什么?
【问题讨论】:
标签:
performance
database-design
architecture
relational-database
database-schema
【解决方案1】:
是必须的……
我想说,在这种情况下,最好使用查找表。
如果你有一个简单的活动/非活动或是/否列,你可以只使用一个 char(1) 和一个检查约束或一点,但如果你代表任何更复杂的东西,最好有一个查找表。
然后您可以将此表用于用户表单输入(填充选择框等)
这将展平和缩小列,这将允许每页有更多行,并有助于缓存主表的内存使用情况。
【解决方案2】:
从性能的角度来看,查找表在大多数数据库系统中基本上是免费的。 SQL 分析器/执行器将在内存中加载整个查找表,如果它足够小的话。
如果需要,添加允许用户或管理员添加更多支付类型的功能很容易。
【解决方案3】:
当您需要 a) 限制列中值的范围,以及 b) 在运行时更改值的范围时,请使用“查找表”。
目前,对于每个表行,此 payment_type 字段都被存储
作为文本。现在最好将此值存储为文本或进行查找
表并将外键存储回事务表中?
您似乎在混合两种不同且不相关的想法。
- 使用“查找表”(我认为它是“表和外键约束”的简写)。
- 用 ID 号替换文本。
要创建一个“查找表”来限制“事务”表中“payment_type”的值范围,您可以这样做。
create table payment_types (
payment_type varchar (35) primary key
);
insert into payment_types
select distinct payment_type
from transactions;
alter table transactions
add constraint constraint_name
foreign key (payment_type)
references payment_types (payment_type);
当您谈论货币交易时,您可能不想级联更新或删除。巨大的、巨大的伤害的风险是相当高的。
如果您想减小事务表的宽度,请考虑使用小的 CHAR() 代码而不是整数。人类可读的代码可以避免连接。在您的情况下,我可能会使用“cc”、“dc”和“it”。但我只会在分析所有已知的付款类型后才会这样做。 (会计人员知道,不仅是数据库开发人员知道的,也不仅仅是在您的特定公司中使用的人员。)
create table payment_types (
payment_type_code char(2) primary key,
payment_type_desc varchar(35) not null unique
);
如果 CHAR(2) 代码无法覆盖您的预期值,请使用整数,并支付连接的代价以获得人类可读的值。
【解决方案4】:
我看到了使用参考表的几个好处:
数据库可以应用完整性约束。任何人都不能有意或无意地输入'Playpal' 服务——除非他有权访问引用表。
为各种应用程序(或部件)拆分访问权限更加容易。一些应用程序可以访问transcations 表并且只能读取引用表的权限,其他(管理面板)也可以写入引用表。
transaction 表的整体尺寸较小。
transaction 表的行大小较小。
在这种特殊情况下,行大小也保持不变。
包含payment_type 的各种索引现在包含payment_type_id,因此它们更小了。
前面的四个属性可能有助于更快的查询,而不是更慢的查询,因为较小的表和索引大小意味着更多的数据可以在内存中保留更长的时间。