好的,我被要求准备一个大学数据库,我被要求以某种方式存储某些数据。
例如,我需要存储一个课程代码,该代码有一个字母,后跟两个整数。例如I45、D61等。
所以应该是VARCHAR(3)我说得对吗?但我仍然不确定这是否是正确的道路。我也不确定如何在SQL脚本中实现这一点。
我似乎在笔记中找不到任何答案,我正在为这个问题编写数据字典,然后才插手编写脚本。
有什么建议吗?
最佳答案
尽可能使主键没有业务意义。您可以轻松地更改数据库设计,而不会严重影响应用程序层。对于哑主键,用户不会将含义与某个记录的标识符相关联。
您所查询的内容被称为智能密钥,通常是用户可见的。非用户可见的密钥称为哑密钥或代理密钥,有时该非用户可见的密钥变为可见,但这不是问题,因为大多数哑密钥不是由用户解释的。例如,无论您想更改此问题的标题,此问题的id将保持不变https://stackoverflow.com/questions/10412621/
对于智能主键,有时出于美观的原因,用户希望指定该键的格式和外观。而且这可以很容易地得到经常更新,用户感觉。这将是应用程序方面的一个问题,因为这需要将更改级联到相关表上;数据库方面也是,因为级联更新相关表上的键是非常耗时的
请在此处阅读详细信息:
http://www.bcarter.com/intsurr1.htm
代理密钥的优点:http://en.wikipedia.org/wiki/Surrogate_key
可以在代理密钥(也称为哑密钥)旁边实现自然密钥(也称为智能密钥)
-- Postgresql has text type, it's a character type that doesn't need length,
-- it can be upto 1 GB
-- On Sql Server use varchar(max), this is upto 2 GB
create table course
(
course_id serial primary key, -- surrogate key, aka dumb key
course_code text unique, -- natural key. what's seen by users e.g. 'D61'
course_name text unique, -- e.g. 'Database Structure'
date_offered date
);
这种方法的优点是,当学校在未来某个时间点扩张时,他们决定提供一个西班牙语的数据库结构,你的数据库与用户引入的用户解释值是隔离的。
假设您的数据库已开始使用智能密钥:
create table course
(
course_code primary key, -- natural key. what's seen by users e.g. 'D61'
course_name text unique, -- e.g. 'Database Structure'
date_offered date
);
接着是西班牙语的数据库结构课程。如果用户向您的系统介绍自己的规则,他们可能会尝试在课程代码值中输入以下内容:
D61/ESP,其他将按ESP-D61、ESP:D61执行。如果用户决定了自己的主键规则,事情可能会失控,然后他们会告诉你根据他们根据主键格式创建的任意规则来查询数据,例如“列出我们在这所学校提供的所有西班牙语课程”,这不是一个史诗般的要求吗那么,一个好的开发人员会做些什么来适应数据库设计的变化呢?他/她将正式确定数据结构,重新设计表格:
create table course
(
course_code text, -- primary key
course_language text, -- primary key
course_name text unique,
date_offered date,
constraint pk_course primary key(course_code, course_language)
);
你看到问题了吗?这将导致停机,因为您需要将更改传播到依赖于该课程表的表的外键。当然,您还需要首先调整这些依赖表。看看它不仅会给DBA带来麻烦,也会给dev带来麻烦。
如果从一开始就使用哑主键,即使用户在不知情的情况下向系统引入规则,也不会对数据库设计带来任何大规模的数据更改或数据架构更改。这可以为你争取时间相应地调整你的应用程序。然而,如果您将智能放在主键中,那么像上面这样的用户需求可以使您的主键自然地转为复合主键。这不仅对数据库设计的重构和数据的大量更新是困难的,而且对您的应用程序快速适应新的数据库设计也是困难的。
create table course
(
course_id serial primary key,
course_code text unique, -- natural key. what's seen by users e.g. 'D61'
course_name text unique, -- e.g. 'Database Structure'
date_offered date
);
因此,使用代理密钥,即使用户在课程代码中隐藏了新规则或信息,您也可以安全地将更改引入表中,而不必强制您快速调整应用程序以适应新的设计。您的应用程序仍然可以继续,不需要停机。它真的可以让你有时间随时调整你的应用程序。这将是对特定语言课程的更改:
create table course
(
course_id serial primary key,
course_code text, -- natural key. what's seen by users e.g. 'D61'
course_language text, -- natural key. what's seen by users e.g. 'SPANISH'
course_name text unique, -- e.g. 'Database Structure in Spanish'
date_offered date,
constraint uk_course unique key(course_code, course_language)
);
如您所见,您仍然可以执行一个大的
UPDATE
语句,将用户对课程代码施加的规则拆分为两个字段,而这两个字段不需要对依赖表进行更改。如果使用智能复合主键,重新构造数据将迫使您将复合主键上的更改级联到依赖表的复合外键。使用dumb主键,您的应用程序仍将照常运行,您可以随时根据新的设计修改应用程序的更改(例如,新的文本框,用于课程语言)。对于dumb主键,依赖表不需要复合外键来指向course表,它们仍然可以使用相同的旧dumb/surrogate主键而且对于哑主键,主键和外键的大小也不会扩展
关于mysql - Course_code的适当数据类型是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10412621/