何时用ID替换数据库列

时间:2014-10-16 18:59:02

标签: mysql sql database-design

我正在帮朋友设计一个数据库,但我很好奇是否有以下的一般经验法则:

TABLE_ORDER

  • ORDERNUMBER
  • 订单类型

OrderType列可以来自预设的订单类型列表。我应该允许在OrderType列中使用VARCHAR值(例如生产订单,销售订单等等)或者我应该将其分成另一个表并将其作为外键引用而不是TABLE_ORDER作为以下内容?:

TABLE_ORDER

  • ORDERNUMBER
  • OrderTypeID

TABLE_ORDER_TYPE

  • ID
  • 订单类型

4 个答案:

答案 0 :(得分:1)

如果订单类型列表已设置且不会更改,您可以选择不制作单独的表格。但在这种情况下,请不要将其设为VARCHAR,而应将其设为ENUM

您可以更好地对此进行索引,并且最终可能会使用与使用查找表创建ID的数据库相同的数据库。

但如果有任何改变你需要添加类型,那就去第二个。您可以稍后添加界面,但您可以轻松制作“获取所有类型”类型的页面等。

答案 1 :(得分:1)

我会说使用另一个表格说“ReferenceCodes”例如:

类型,名称,描述,代码

然后,您可以在整个数据库中使用代码,无需担心与该代码关联的名称。如果您使用名称(例如您的情况下的订单类型),那么稍后更改名称将非常困难。这就是我们在系统中实际做的事情。

答案 2 :(得分:0)

在完美的世界中,任何可以包含重复数据的列都应该是id或ENUM。这有助于确保数据始终在内部一致,并且可以减少数据库大小并加快查询速度。

对于类似这种结构的东西,我可能会创建一个master_object表,可以用于多种类型。 OrderType将引用master_object表。然后,您可以将同一个表用于其他数据。例如,假设您有另一个表 - 付款,其中包含一列PaymentType。您可以使用master_object表来存储该列的值和元数据。这为您提供了相当大的灵活性,而不必强迫您创建一堆小表,每个表包含2-10行。

布赖恩

答案 3 :(得分:0)

如果列表很小(少于10个项目),那么您可以选择将其建模为第一个,但添加列约束以限制列表中值的输入。这会强制条目属于您的列表,但您的列表不应经常更改。

e.g。检查('Val1','Val2',......'Valn')中的order_type

如果列表会改变,如果它在多个表中使用,则需要支持多种语言或任何其他需要变化的设计标准,然后创建类型表(使用此选项总是安全的,它是为什么它是最常用的。)

您可以将所有此类表格收集到“代码”表中,该表概括了概念

CREATE TABLE Codes (
Code_Class CHARACTER VARYING(30)  NOT NULL,
Code_Name CHARACTER VARYING(30)  NOT NULL,
Code_Value_1 CHARACTER VARYING(30),
Code_Value_2 CHARACTER VARYING(30),
Code_Value_3 CHARACTER VARYING(30),
CONSTRAINT PK_Codes PRIMARY KEY (Code_Class, Code_Name)

);

insert into codes ( code_class, code_name, code_value_1 )
        values( 'STATE','New York','NY' ),
        values( 'STATE, 'California','CA'), 
        .... );

然后,您可以在table.column上放置和更新UPDATE / INSERT触发器,该更改应限制为状态列表。假设一个employee表有一个EMP_STATE列来保存状态短格式。

触发器只会调用类似

的select语句
SELECT code_name
     , code_value_1
  INTO v_state_name, v_state_short_name
  FROM codes
 WHERE code_class = 'STATE'
   AND code_value_1 = new.EMP_STATE;

if( not found ) then
   raise( some error to fail the trigger and the insert );
end if;

这可以扩展到其他类型:

insert into codes ( code_class, code_name )
        values( 'ORDER_TYPE','Production' ),
        values( 'ORDER_TYPE', 'Sales'), 
        .... );

select code_name
     , code_value_1
  into v_state_name, v_state_short_name
  from codes
 where code_class = 'ORDER_TYPE'
   and code_name = 'Sales';

这种最后一种方法虽然普遍适用,但可以过度使用。它的缺点是你不能使用不同的数据类型(code_name,code_value _ *)。

一般的经验法则:创建一个'TYPE'(例如ORDER_TYPE)表(用于保存您希望为每种类型约束属性的值),使用ID作为主键,使用单个序列生成所有这些id(适用于所有'TYPE'表)。许多TYPE表可能会使您的模型混乱,但您的开发人员会明白其含义(最终目标)。