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我通常是第一个抱怨的人,