许可证规范化 类
Normalization of Licence Classes
如何存储有关 class 个许可证的数据?
数据子集是拥有执照的人和拥有执照的人 类。
感谢@karmakaze 绘制此图。
+------+ +-------+ +---------+
|person|---*|licence|---1*|lic_class|
+------+ +-------+ +---------+
people
table 有 person_id
和各种名称字段。
许可证具有由政府机构颁发的具有有效期的唯一编号,许可证有多个 classes。
最初我打算将 licenses
table 构造为 lut_training
(上面的 a.k.a lic_class)和之间的链接 table people
CREATE TABLE `licences` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`person_id` int(10) unsigned NOT NULL,
`training_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `person_id` (`person_id`),
KEY `training_id` (`training_id`),
CONSTRAINT `licences_ibfk_3` FOREIGN KEY (`person_id`) REFERENCES `people` (`person_id`) ON UPDATE CASCADE,
CONSTRAINT `licences_ibfk_4` FOREIGN KEY (`training_id`) REFERENCES `lut_training` (`training_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
lut_training
table 最初只是一个查找 table 来处理许可证 classes 的短名称和长名称,例如(id="6", short="1F", long="1F 武装警卫队")。
然后我需要将 licence_number
和 expiry_date
放在某个地方,这样它就可以进入 licences
(可能是它的最佳位置)或 lut_training
。我选择了 lut_training
,但这可能是糟糕的数据库设计。
CREATE TABLE `lut_training` (
`training_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`training_short` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`training_long` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`expiry_date` date DEFAULT NULL,
`licence_number` int(10) unsigned NOT NULL,
PRIMARY KEY (`training_id`),
KEY `training_long` (`training_long`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
然后我发现每个许可证 class 都没有自己的编号或有效期,这与我拥有的其他 8 个政府许可证不同。加上classes可以随意增减。所以将 expiry_date 和 licence_number 字段放在 lic_class
table.
中是没有意义的
10 class 目前存在 1A,1B,1C,1D,1E,1F,2A,2B,2C,2D。有人可能从 1A 和 1E 开始,添加 1C,然后删除 1A 并保留 1E 和 1C,直到他们的许可证到期。
所以现在创建 lut_training
并为每个许可证放一行 class 似乎很愚蠢且效率低下,因为数据集中的大多数人都是多人 class 被许可人。
所以我可以这样做并使用 licence
中的 1 个字段来持有许可证的 classes:
+------+ +-------+
|person|---*|licence|
+------+ +-------+
这有点像 WordPress.org wp_options
table 是一堆 key:value 对。
作为SQL
CREATE TABLE `licences` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`person_id` int(10) unsigned NOT NULL,
`expiry_date` date DEFAULT NULL,
`licence_number` int(10) unsigned NOT NULL,
`licence_types` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `person_id` (`person_id`),
CONSTRAINT `licences_ibfk_3` FOREIGN KEY (`person_id`) REFERENCES `people` (`person_id`) ON UPDATE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我遇到的问题是
licence_types varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
甚至 licence_types smallint NOT NULL,
这似乎违反了数据库规范化,特别是 1NF 第一范式。
此外,如果我使用字符串或整数字段而不是单独的 lic_class
table,我将不得不进行字符串或整数操作以更新许可证 classes。 10 license classes 表示 2^10=1024 位数据或一些伪数组或文字数组字段,用于存储一个人持有的所有 license class 组合。这不是很多 space.
感谢有关如何解决此问题的指导。
希望批评者更清楚这一点。
据我所知,一个人可以拥有零个或多个许可证(来自不同政府),每个许可证可以有一个或多个许可 classes。
+------+ +-------+ +---------+
|person|---*|licence|---1*|lic_class|
+------+ +-------+ +---------+
到期日期将与许可证一起使用。您可以选择将许可 classes 反规范化为许可,具体取决于每个许可 class.
数据的 much/little 方式。
棘手的一点是约束。 license (person_id, government)
上应该有唯一约束。 lic_class(licence_id, license_type)
也应该有一个唯一的约束,因为你不能多次拥有相同的类型。
如何存储有关 class 个许可证的数据?
数据子集是拥有执照的人和拥有执照的人 类。
感谢@karmakaze 绘制此图。
+------+ +-------+ +---------+
|person|---*|licence|---1*|lic_class|
+------+ +-------+ +---------+
people
table 有 person_id
和各种名称字段。
许可证具有由政府机构颁发的具有有效期的唯一编号,许可证有多个 classes。
最初我打算将 licenses
table 构造为 lut_training
(上面的 a.k.a lic_class)和之间的链接 table people
CREATE TABLE `licences` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`person_id` int(10) unsigned NOT NULL,
`training_id` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `person_id` (`person_id`),
KEY `training_id` (`training_id`),
CONSTRAINT `licences_ibfk_3` FOREIGN KEY (`person_id`) REFERENCES `people` (`person_id`) ON UPDATE CASCADE,
CONSTRAINT `licences_ibfk_4` FOREIGN KEY (`training_id`) REFERENCES `lut_training` (`training_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
lut_training
table 最初只是一个查找 table 来处理许可证 classes 的短名称和长名称,例如(id="6", short="1F", long="1F 武装警卫队")。
然后我需要将 licence_number
和 expiry_date
放在某个地方,这样它就可以进入 licences
(可能是它的最佳位置)或 lut_training
。我选择了 lut_training
,但这可能是糟糕的数据库设计。
CREATE TABLE `lut_training` (
`training_id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`training_short` varchar(10) COLLATE utf8mb4_unicode_ci NOT NULL,
`training_long` varchar(50) COLLATE utf8mb4_unicode_ci NOT NULL,
`expiry_date` date DEFAULT NULL,
`licence_number` int(10) unsigned NOT NULL,
PRIMARY KEY (`training_id`),
KEY `training_long` (`training_long`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
然后我发现每个许可证 class 都没有自己的编号或有效期,这与我拥有的其他 8 个政府许可证不同。加上classes可以随意增减。所以将 expiry_date 和 licence_number 字段放在 lic_class
table.
10 class 目前存在 1A,1B,1C,1D,1E,1F,2A,2B,2C,2D。有人可能从 1A 和 1E 开始,添加 1C,然后删除 1A 并保留 1E 和 1C,直到他们的许可证到期。
所以现在创建 lut_training
并为每个许可证放一行 class 似乎很愚蠢且效率低下,因为数据集中的大多数人都是多人 class 被许可人。
所以我可以这样做并使用 licence
中的 1 个字段来持有许可证的 classes:
+------+ +-------+
|person|---*|licence|
+------+ +-------+
这有点像 WordPress.org wp_options
table 是一堆 key:value 对。
作为SQL
CREATE TABLE `licences` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`person_id` int(10) unsigned NOT NULL,
`expiry_date` date DEFAULT NULL,
`licence_number` int(10) unsigned NOT NULL,
`licence_types` varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
PRIMARY KEY (`id`),
KEY `person_id` (`person_id`),
CONSTRAINT `licences_ibfk_3` FOREIGN KEY (`person_id`) REFERENCES `people` (`person_id`) ON UPDATE CASCADE,
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
我遇到的问题是
licence_types varchar(40) COLLATE utf8mb4_unicode_ci NOT NULL,
甚至 licence_types smallint NOT NULL,
这似乎违反了数据库规范化,特别是 1NF 第一范式。
此外,如果我使用字符串或整数字段而不是单独的 lic_class
table,我将不得不进行字符串或整数操作以更新许可证 classes。 10 license classes 表示 2^10=1024 位数据或一些伪数组或文字数组字段,用于存储一个人持有的所有 license class 组合。这不是很多 space.
感谢有关如何解决此问题的指导。
希望批评者更清楚这一点。
据我所知,一个人可以拥有零个或多个许可证(来自不同政府),每个许可证可以有一个或多个许可 classes。
+------+ +-------+ +---------+
|person|---*|licence|---1*|lic_class|
+------+ +-------+ +---------+
到期日期将与许可证一起使用。您可以选择将许可 classes 反规范化为许可,具体取决于每个许可 class.
数据的 much/little 方式。棘手的一点是约束。 license (person_id, government)
上应该有唯一约束。 lic_class(licence_id, license_type)
也应该有一个唯一的约束,因为你不能多次拥有相同的类型。