Mysql 规范化顺序/顺序

Mysql 规范化顺序/顺序,mysql,sql,database-design,database-normalization,Mysql,Sql,Database Design,Database Normalization,我无法在谷歌或其他任何地方找到解决方案。也许我的术语错了 我正试图找出如何在MySQL中规范化这样一个表中的排序: | id | job | action | sequence | | :- | :---- | :------------- | :------- | | 1 | build | Procure Wood | 1 | | 2 | build | Grab Hammer | 2 | | 3 | build | Hamme

我无法在谷歌或其他任何地方找到解决方案。也许我的术语错了

我正试图找出如何在
MySQL
中规范化这样一个表中的排序:

| id | job   | action         | sequence |
| :- | :---- | :------------- | :------- |
| 1  | build | Procure Wood   | 1        |
| 2  | build | Grab Hammer    | 2        |
| 3  | build | Hammer         | 3        |
| 4  | drill | Get Screw      | 1        |
| 5  | drill | Charge Drill   | 2        |
| 6  | drill | Start Drilling | 3        |
请忽略以下事实:
作业
操作
列均未规范化,这不是问题的一部分,只是示例的一部分

例如,如果我现在想为
build
作业插入一个新操作
Get Nails
,该怎么办。这将在
抓锤
之后,但在
抓锤
之前。如果它被简单地插入(然后
按作业顺序,顺序
),您将得到以下结果:

| id | job   | action         | sequence     |
| :- | :---- | :------------- | :----------- |
| 1  | build | Procure Wood   | 1            |
| 2  | build | Grab Hammer    | 2            |
| 7  | build | Get Nails      | 3            |
| 3  | build | Hammer         | 3 <- problem |
| 4  | drill | Get Screw      | 1            |
| 5  | drill | Charge Drill   | 2            |
| 6  | drill | Start Drilling | 3            |
| id |作业|动作|序列|
| :- | :---- | :------------- | :----------- |
|1 |建造|采购木材| 1|
|2 |建造|抓斗锤| 2|
|7 |修|钉| 3|

|3 | build | Hammer | 3将此过程视为两个步骤,因此,首先使用空序列号将新操作添加(插入)到表中。然后将其“移动”到正确的位置(更新),将其id设置为3,并将所有相关操作(大于或等于3)的id设置为序列+1

  DROP TABLE IF EXISTS my_table;

CREATE TABLE my_table  (
      `id` Serial primary key,
      `job` varchar(12),
      `action` VARCHAR(20),
      `sequence` int);

    INSERT INTO my_table 
      (`id`, `job`, `action`, `sequence`)
    VALUES
      ('1', 'build', 'Procure Wood',1),
      ('2', 'build', 'Grab Hammer',2),
      ('3', 'build', 'Hammer',3),
      ('4', 'drill', 'Get Screw',1),
      ('5', 'drill', 'Charge Drill',2),
      ('6', 'drill', 'Start Drilling',3);

SELECT * FROM my_table ORDER BY job,sequence; 
+----+-------+----------------+----------+
| id | job   | action         | sequence |
+----+-------+----------------+----------+
|  1 | build | Procure Wood   |        1 |
|  2 | build | Grab Hammer    |        2 |
|  3 | build | Hammer         |        3 |
|  4 | drill | Get Screw      |        1 |
|  5 | drill | Charge Drill   |        2 |
|  6 | drill | Start Drilling |        3 |
+----+-------+----------------+----------+

      insert into my_table
      (job,action,sequence) values 
      ('build','grab nails',null);

      UPDATE my_table x 
        JOIN 
           ( SELECT a.id
                  , CASE WHEN a.sequence IS NULL THEN 3 
                         WHEN a.sequence >=3 THEN a.sequence +1 ELSE a.sequence 
                     END new_seq     
               FROM my_table a
               JOIN my_table b
                 ON b.job = a.job
              WHERE b.id = LAST_INSERT_ID()
           ) y 
          ON y.id = x.id 
         SET x.sequence = y.new_seq; 

SELECT * FROM my_table ORDER BY job,sequence;
+----+-------+----------------+----------+
| id | job   | action         | sequence |
+----+-------+----------------+----------+
|  1 | build | Procure Wood   |        1 |
|  2 | build | Grab Hammer    |        2 |
|  7 | build | grab nails     |        3 |
|  3 | build | Hammer         |        4 |
|  4 | drill | Get Screw      |        1 |
|  5 | drill | Charge Drill   |        2 |
|  6 | drill | Start Drilling |        3 |
+----+-------+----------------+----------+

规范化是指从数据库中删除冗余和逻辑错误。冗余通常会导致逻辑错误,尽管在大多数情况下,这些错误是由于没有设计方法,或者是由于直接跳入物理设计

下面是一个可能的逻辑设计示例

--已存在名为Job\u NAME的作业
--
作业{job_NAME}
PK{JOB_NAME}
--名为Action\u NAME的操作已存在。
--
动作{action_NAME}
PK{ACTION_NAME}
--作业作业名称涉及动作动作名称。
--
作业操作{作业名称,操作名称}
PK{JOB_NAME,ACTION_NAME}
FK1{JOB_NAME}引用了JOB{JOB_NAME}
FK2{ACTION_NAME}引用了ACTION{ACTION_NAME}
--操作操作名称在作业作业名称中有关联的步骤编号步骤编号。
--
作业步骤{作业名称,步骤编号,操作名称}
PK{作业名称,步骤编号}
FK1{JOB_NAME,ACTION_NAME}引用JOB_ACTION{JOB_NAME,ACTION_NAME}
此时,您可以开始考虑物理设计:列索引的大小等,并决定添加数字
id
以用于
PKs
。根据数据库大小、RDBMS和使用的硬件,您可以决定保持原样。我故意避免在此时添加
id


例如PostgreSQL(安装了它)——应该很容易为MySQL进行调整。对于MySQL,使用
varchar(25)
而不是
TEXT
,示例应该可以正常工作(未经测试)

创建表作业(
作业名称文本不为空
,约束主键作业主键(作业名称)
);
创建表操作(
操作名称文本不为空
,约束主键动作主键(动作名称)
);
创建表作业\u操作(
作业名称文本不为空
,操作名称文本不为空
,约束主键\作业\操作主键(作业\名称,操作\名称)
,约束fk1\u作业\u操作
外键(作业名称)引用
作业(作业名称)
,约束fk2_作业_操作
外键(操作名称)引用
动作(动作名称)
);
创建表作业\u步骤(
作业名称文本不为空
,操作名称文本不为空
,步骤_无BIGINT不为空
,约束主键,作业步骤主键(作业名称,步骤编号)
,约束fk1\u作业\u步骤
外键(作业名称、操作名称)引用
作业操作(作业名称、操作名称)
);
插入一些测试数据;请注意,步骤编号不是连续的,为以后的中间步骤留有空间

插入作业(作业名称)
价值观
(“构建”)
,(“钻孔”)
;
插入到动作\中(动作\名称)
价值观
(“采购木材”)
,(“抓斗锤”)
,(“锤子”)
,('get screw')
,(“装药钻”)
,(“开始钻探”)
;
插入作业操作(作业名称、操作名称)
价值观
(“建造”、“采购木材”)
,(“建造”、“抓斗锤”)
,(“建造”、“锤子”)
,('drill','get screw')
,(“钻机”、“装药钻机”)
,(“钻孔”,“开始钻孔”)
;
插入作业步骤(作业名称、操作名称、步骤编号)
价值观
(“建造”,“采购木材”,1000000)
,('build','grab hammer',2000000)
,('build','hammer',3000000)
,('drill','get screw',1000000)
,('drill','charge drill',2000000)
,(“钻探”,“开始钻探”,3000000)
;
查询返回正确的结果

选择作业名称
,rank()作为步骤(按作业划分\u名称顺序按步骤划分\u无ASC)
,行动名称
从job_步骤
按职务名称排序;
+----------+------+----------------+
|作业|名称|步骤|操作|名称|
+----------+------+----------------+
|建造| 1 |采购木材|
|建造| 2 |抓斗锤|
|建造| 3 |锤|
|钻| 1 |取螺丝|
|钻孔| 2 |装药钻孔|
|钻孔| 3 |开始钻孔|
+----------+------+----------------+
并在构建作业中插入
get nails

--首先定义新操作
在action_(action_名称)中插入值(“获取钉子”);
--将其与构建作业关联
插入作业操作(作业名称、操作名称)
值(“构建”、“获取钉子”);
--在抓斗锤子和锤子之间插入
插入作业步骤(作业名称、操作名称、步骤编号)
值('build'、'get nails',2500000);
现在查询返回:

+----------+------+----------------+
|作业|名称|步骤|操作|名称|
+----------+------+----------------+
|建造| 1 |采购木材|
|建造| 2 |抓斗锤|
|修| 3 |修指甲|
|造| 4 |锤|
|钻| 1 |取螺丝|
|钻孔| 2 |装药钻孔|
|钻孔| 3 |开始钻孔|
+----------+------+----------------+

作业和操作似乎是normalised@philipxy我通常是第一个抱怨的人,