Mysql 何时用ID替换数据库列

Mysql 何时用ID替换数据库列,mysql,sql,database-design,Mysql,Sql,Database Design,我正在帮助一位朋友设计一个数据库,但我很好奇以下方面是否有一般的经验法则: 表格顺序 订单号 订单类型 列OrderType可能来自订单类型的预设列表。我应该允许在OrderType列(例如生产订单、销售订单等)中使用VARCHAR值,还是应该将其分离到另一个表中,并将其作为外键引用,而不是从表\订单中引用,如下所示: 表格顺序 订单号 订单类型ID 表格\订单\类型 身份证 订单类型 如果订单类型列表已设置且不会更改,您可以选择不制作单独的表格。但在这种情况下,不要将其设置为VARC

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

表格顺序

  • 订单号
  • 订单类型
列OrderType可能来自订单类型的预设列表。我应该允许在OrderType列(例如生产订单、销售订单等)中使用VARCHAR值,还是应该将其分离到另一个表中,并将其作为外键引用,而不是从表\订单中引用,如下所示:

表格顺序

  • 订单号
  • 订单类型ID
表格\订单\类型

  • 身份证
  • 订单类型

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

您可以更好地对此进行索引,并且最终得到的数据库类型可能与使用查找表将其设置为ID时的数据库类型相同


但是,如果您需要添加任何类型,只需进行第二种更改。您可以稍后添加一个接口,但您可以轻松地将“获取所有类型”的页面设置为页面等。

在理想情况下,任何包含重复数据的列都应该是id或枚举。这有助于确保数据始终在内部保持一致,可以减少数据库大小并加快查询速度

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


Brian

我想使用另一个表,比如说“ReferenceCodes”:

类型、名称、说明、代码

然后,您可以在整个数据库中使用代码,而不必担心与该代码关联的名称。如果您使用一个名称(例如,您的案例中的订单类型),那么以后更改名称将非常困难。这就是我们在系统中实际执行的操作。

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

e、 g.检查订单\输入('Val1'、'Val2'、…'Valn')

如果列表会发生变化,如果在多个表中使用,则要求您支持多种语言或任何其他要求可变性的设计标准,然后创建您的类型表(您总是安全地使用此选项,这就是为什么它使用最多的原因)

您可以将所有这样的表收集到一个“codes”表中,该表概括了这个概念

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)
))

然后,您可以在“更改”下的table.column上放置并更新/插入触发器,该更改应被约束到状态列表中。假设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\u name、code\u value)


一般的经验法则是:创建一个“类型”(例如ORDER_TYPE)表(保存您希望为每个类型约束属性的值),使用ID作为主键,使用单个序列生成所有此类ID(对于所有“类型”表)。许多类型表可能会使您的模型变得杂乱无章,但您的开发人员会很清楚其中的含义(最终目标)。

您的第一段非常离谱。使用“id”和“ENUM”隐含的数据完整性约束可以在没有这些约束的情况下很好地实现。以这种方式替换每一个重复的专栏都是不可能的,更不用说“完美”甚至是明智的了。
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';