【问题标题】:ER/Relational Table to DatabaseER/关系表到数据库
【发布时间】:2020-03-26 15:57:25
【问题描述】:

所以我有以下 SQL 命令用于下面的描述。我不确定我是否有正确的约束,特别是对于外键,以及何时使用 not null 以及何时不使用。有人可以根据数据库描述验证命令是否正确吗?

  1. 汽车经销商有唯一的企业 ID 号、经销商名称、城市、州和唯一的 网址。商家 ID 是一个介于 1000-9999 之间的数字。
  2. 销售人员有名字、姓氏、年龄、性别和唯一的员工 ID 号。员工编号在 100-999 范围内。
  3. 客户有名字、姓氏、城市、州、性别、年龄和唯一的纳税人身份证号。纳税人身份证号为 9 位数字。
  4. 汽车有品牌、型号、年份、建议价格和唯一的车辆 ID 号。一辆车可以有(可能有多种)颜色,这些颜色应该被建模为一个属性。注意:汽车的品牌是制造商(例如,福特、本田、宝马)​​,型号是车型的名称(例如,思域、雅阁、CRX)。
  5. 销售人员为经销商工作。为了进入数据库,销售人员必须为经销商工作。但是,数据库中可能存在没有任何销售人员的经销商。经销商有许多为他们工作的销售人员,一个销售人员可能为许多不同的经销商工作。数据库应记录销售人员开始为经销商工作的开始日期。
  6. 经销商拥有汽车。经销商可能拥有许多汽车,或者他们可能完全没有库存并且拥有零辆汽车。一辆车只能由一个经销商拥有,并且必须由经销商拥有才能进入数据库。数据库应记录经销商购买汽车的日期和经销商为汽车支付的价格。
  7. 销售人员向客户销售汽车。即使销售人员没有向客户出售任何汽车,它们仍应存储在数据库中。但是,数据库应该只存储从销售人员那里购买汽车的客户的信息。无论经销商是否已售出,有关经销商拥有的汽车的信息都应存储在数据库中。一个销售人员可能只将一辆特定的汽车卖给一个客户。同样,客户可以 仅从一个销售人员处购买特定汽车。但是,客户可能会从同一个销售人员那里购买不止一辆汽车。当销售人员向客户销售汽车时,应将销售价格和日期记录在数据库中。

create table Car_dealership(
Business_id int check ( 1000 >= business_id <= 9999),
b_name varchar(30) not null,
b_city varchar(20) not null,
b_state char(2) not null,
web_url varchar(100) not null,
primary key (Business_id)
);

create table salesperson (
employee_id int check ( 100 >= employee_id <= 999),
first_name varchar (30) not null,
last_name varchar (30),
age int check (0 < age < 130) , 
gender char(1),
/* assumed gender is either Male (M) or Female (F) */
primary key (employee_id)
);

create table customers (
taxpayer_id decimal(9,0),
first_name varchar (30) not null,
last_name varchar (30),
age int check (0 < age < 130), 
gender char(1),
/* assumed gender is either Male (M) or Female (F) */
city varchar (20),
state char(2),
primary key (taypayer_id),
);

create table cars (
vehicle_id int,
make varchar(30),
model varchar(30),
make_year year,
suggested_price int, 
business_id int, 
date_acquired date,
price_paid int,
primary key (vehicle_id),
foreign key(business_id) references Car_Dealerships (business_id)
);

create table car_colors (
vehicle_id int,
colors varchar (30),
primary key (vehicle_id),
foreign key(vehicle_id) references cars (vehicle_id)
);

create table works_for (
business_id int,
employee_id int,
start_date date not null,
primary key (business_id, employee_id),
foreign key(business_id) references Car_Dealerships (business_id),
foreign key(employee_id) references salesperson (employee_id) 
);

create table sells (
vehicle_id int,
taxpayer_id int,
employee_id int,  
sale_price int, 
date_sold date,
primary key (vehicle_id) ,
foreign key(vehicle_id) references cars (vehicle_id),
foreign key(taxpayer_id) references customers (taxpayer_id),
foreign key(employee_id) references salesperson (employee_id)
);

【问题讨论】:

  • 您的教科书会告诉您如何执行此操作,这是一个常见问题解答。请参阅How to Ask 和投票箭头鼠标悬停文本。问一个具体的问题。但是给出你正在使用的参考,有很多方法。请use text, not images/links, for text--including tables & ERDs。转述或引用其他文本。只提供您需要的东西并将其与您的问题联系起来。仅将图像用于无法表达为文本或增强文本的内容。无法搜索或剪切和粘贴图像。在图片中包含图例/键和说明。
  • (post-edit) 请在发帖前查看您帖子的格式化版本。请阅读有关块代码格式的信息。此外,您剩余的链接图不是标准符号,请给出图例,除非它可以清楚地在文本中给出。当你得到它时,你被告知如何阅读它。如果您不知道如何阅读其中的一部分,请说出哪一部分以及为什么。我只是重复我上一条评论所说的话。
  • 您遇到的具体问题是什么?只提供必要的东西。请不要放弃你的整个作业。 PS你仍然没有说你认为你应该做什么。 FK 表示子行必须作为 UNIQUE 出现在其他地方。如果是这样且不是其他声明的结果,请声明它。就您被告知要做的事情而言,您有什么问题?

标签: sql database foreign-keys relational-database entity-relationship


【解决方案1】:

问题•“教育”

回答您的问题相当容易。我拿了你的文字,很快就完成了。我们在现实世界中已经拥有了 50 年的技术和方法:

  1. 理论
    关系模型

35 年:

  1. 关系数据建模
    IDEF1X,关系数据建模标准,
    请注意,它是图形的,而不是文本的。

  2. SQL 平台
    一个真正的平台,关系模型的数据子语言。
    请注意,有许多假装 sql 提供程序(不是 SQL,因为它们不符合 SQL 标准;没有 ACID 事务;等等)
    提供套件(不是平台,因为它们没有服务器架构;没有像样的并发性等)。

  3. 模型,而不是文本
    见上文[2]。

    • 请注意,文字和单字符符号使用左半球(脑力的 4-6%),而图表使用右脑(脑力的 94-96%)。

(当然,在构建完整的应用程序时需要使用更多的标准,必须提及,但这与您的问题无关,因此在此不一一列举。)子>

所以在现实世界中,至少在高端市场,这是我的领域,生活很容易;直截了当,我们可以正确快速地建模和构建数据库和应用程序,并且可以根据扩展请求轻松更改它们。

但这不是大学和高等教育所教授的内容。正如您的问题所证明的那样,所教的内容以及 StackOverflow 上的数千个类似问题已失效且反关系,大力推广(例如,您的教科书和所有使用它们的教授),被错误地标记为“关系”。本质上是前关系技术,使用前关系方法。

  1. 理论
    1960 年代的记录归档系统,而不是 关系模型,但标记为“关系”。或者更糟糕的是,实际的关系代数,然后要求您从中而不是从数据模型中进行查询。极端原始。

  2. 非关系数据建模
    ERD(直到 1984 年都很棒,但自从使用 IDEF1X 的关系建模出现后就失效了),以及它的几十种变体

    • 与 ERD 不能也不会处理 关系模型 的中心要求(例如关系键,它们是复合自然键)分开,并且与事实上它没有为规范化准备模型,它的细节严重不足;在规范中。

    • 因此,从 ERD 跳转到 SQL DDL 是不可能的,甚至想出一个“改进的”ERD。

    • 而 IDEF1X 标准是在RM之后开发和完善的,专门 RM确实允许模型定义关系组件,例如关系键,确实允许模型从简单元素建模到复杂和详细的规格。

    • 事实上,大多数关系建模工具只需单击一个按钮即可将 SQL 喷射到服务器中,然后数据库就可以进行 DML 编码了。

  3. 文本,而非模型
    在“理论”级别和建模级别上摆弄文本(当我们没有绘图工具或建模工具时,这很棒,但从那以后就已经不复存在了)。这包括在 SQL 代码级别工作以暴露问题并处理它们,而不是在数据模型中或从数据模型中这样做。

严重的障碍

因此,处理给定信息并创建所需结果非常简单。使用自 1984 年以来我们拥有的工具。但是,使用自 1984 年以来已不复存在、过时的古老方法和原始工具即使不是不可能,也非常困难。同时仍保持教学问答环境。

  • 例如。如果您要求我将您从洛杉矶运送到旧金山,我可以在 8 小时内完成(我已经完成了几次)。但是,如果您要求我按照您(教授)的方式进行,使用马和推车,并且每次马累了或马车需要修理时停下来,这将需要更长的时间。

因此,正如您的问题和成千上万的其他问题所证明的那样,您没有接受过所需科学的教育,而是被灌输了虚假的“科学”。随意打印此页,并将其交给您的“教授”。

这个问题,这个练习,实际上是一个很好的,经过深思熟虑的。但是同样,如果不使用关系建模方法(无法使用无腿 ERD 作为建模方法,这是您被“教导”使用的方法,则无法得出正确的答案(满足详细的所有要求)) )。该练习是建模练习,绝对不是翻译(ERD 到 SQL)练习。

我的范围

因此,使用自 1984 年以来我们所拥有的常规工具来回答问题很容易,但从没有必要细节的 ERD 中这样做是不可能的。就像从洛杉矶的马车上跳到刚到旧金山的火车上的座位上一样。

关系数据模型

我会给你结果,一个满足要求的IDEF1X数据模型。标准的强大功能之一是它定义了所需的所有细节(即所有规则和约束),不仅是建模者理解的细节,而且它可以在任何级别呈现必需(表;表键;表键属性;...数据类型;等)。我给你的是 Table-Attribute 级别,你可以计算出所需的 SQL DDL。

    1234563应该能找到解决办法。
  • 是的,我查看了您的记录图,这是一个很好的努力,可以准确地克服我所描述的问题。你的逻辑能力和直觉能力需要得到认可。

注意•符号

  • 我所有的数据模型都在 IDEF1X 中呈现,这是自 1993 年以来为关系数据库建模的标准。

  • 我的IDEF1X Introduction是初学者的必备读物。

注意•内容

  1. 按键
    您的“教授”已将每个层次结构的密钥作为定义的东西,这是唯一的。这是通常教授的 1960 年代记录归档系统之前的街道,其特点是 Record ID 字段。靠着上帝的恩典,你没有被教导那些原始的东西。

    • 但是给这些键起的名字不是很好。所以我保留了它们所包含的内容(不是 id,它具有 RFS 的内涵和限制,而是一个数字,具有范围定义)并给它们起更好、更有意义的名称。
  2. 缺少键
    不知道您是否需要识别缺失的元素(通常是这样)。这些是为了 (a) 防止重复行,或 (b) 确保完整性。我在经销商中提供了备用钥匙;人;和客户。

  3. DealerCar

    汽车只能由一个经销商拥有,并且必须由经销商拥有才能进入数据库。

    • 因此 Car 不是独立的(即使已如此描述,并且给出了唯一密钥)。 (请参阅下面的 FAIL 模型进行比较。)
    • 因此 Car 是 Dependent,它仅存在于由 Dealer 拥有的情况下:DealerCar。这意味着(如 SalesPerson),汽车 PK 是经销商 PK 加上一个差异化因素。
    • 那个区别当然是给定的车钥匙(VehicleNo),主键是(BusinessNo,VehicleNo)。其相关性稍后定义。
    • 另外,为了将 Car 保持为唯一实体,Car Key (VehicleNo) 是 DealerCar 中的备用密钥。
    • 将汽车钥匙作为 AK 一直保留到 CustomerCar 可确保汽车保持唯一性:它只能出售给 1 个客户;它只能由 1 个销售人员出售
  4. 销售人员
    因为一个人可以被多个经销商雇用,所以销售人员的事实,因此关键,不是给定的 (EmployeeNo),而是 (BusinessNo, EmployeeNo)。建模。

  5. 客户汽车

    客户只能从一名销售人员那里购买特定汽车。

    • 说得更好,DealerCar 只能由 1 个销售人员出售
      DealerCar 只能出售给 1 个客户
      根据 VehicleNo 在 CustomerCar 中唯一的事实来实现。

    • 但还有更多。更准确地说,DealerCar(仅由 1 个经销商拥有)只能由该经销商雇用的 SalesPerson 出售。 (否则,SalesPerson 可以出售属于他工作的 Dealer 的 DealerCar。)因此,由于复合关系键的实现:

      • DealerCar PK 在 CustomerCar 中是 1::1
      • CustomerCar 中的 SalesPerson PK 为 1::n,其中 (BusinessNo) 必须与 DealerCar 相同。 (更多内容见下文。)
      • 尽管客户从 1 个 SalesPerson 购买了汽车,但他实际上是从 Dealer::SalesPerson (BusinessNo, EmployeeNo) 购买了 DealerCar。
  6. 汽车颜色

    一辆汽车可以有(可能有多种)颜色,这些颜色应该被建模为一个属性。

    这打破了 1NF: .
    每个属性都必须是平台的原子属性
    .
    对不起,没办法何塞,我不会模型出错。颜色是一个重复的列,它属于一个从属表。建模。

  7. 年龄
    存储变化的值(相对值)是一件非常愚蠢的事情:每年或每个季度,都必须更新表格以反映不断变化的年龄。相对值不是事实,因此不应存储。不变的事实是,人的出生日期。从中可以轻松得出年龄值。


  8. 好关心。由于数据模型是完全规范化的,因此没有 NULL,所有列都是NOT NULL。 Nullable 列清楚地表明规范化不完整。

  9. 业务规则/约束
    数据库是一个自包含和自定义的恢复单元。因此,将所有业务规则和约束、所有事务放在数据库容器中是正确的。但当然,规则的类型不同,部署方式也不同:RULESCHECK 和其他CONSTRAINTS;指数(PRIMARY KEY; UNIQUE);交易(CREATE PROC);等等。

    • 因此必须读取精确的数据模型,并将每个项目转换为适当的 DDL 命令。

    • 此外,所有约束(例如事务)都不能在数据模型中显示(除非扩展)。它们必须记录在流程模型或对象中。事务是数据库 API,在 OO 术语中,它们是方法。

    • 在任何情况下,其余部分(上面没有明确解释的需求规则)都是次要的,很容易从数据模型中读取。如果我在这里给它们,那就是 TLDR(这已经很长了!)。因此我已经给出了那个细节;它是如何实施的;等等,在 PDF 中。享受吧。

SQL DDL

你的任务是你选择任务。您已经为所需的 SQL DDL 提供了第一个剪辑。伟大的工作,跨越了建模的差距。希望您可以阅读 IDEF1X 数据模型,它有更多细节(阅读我的 IDEF1X Introduction,并将 SQL DDL 推进到数据模型中定义的内容。

关系完整性(通过关系键)

练习揭示并因此教导的一件事非常重要,就是这一点。请注意,您的“教授”可能知道也可能不知道或理解这个关系概念:

  • 如果他确实知道这一点,那就太好了,他选择了一种有意识地教授它的练习。

    • 但他没有给你完成练习所需的工具或教育。
  • 如果他不知道这一点,那么他认为正确和完美的答案(无论数据模型类型和 SQL)作为关系解决方案是完全失败的。

我上面给出的关系数据模型当然是正确和完整的。正是因为它采用了 关系键,它们是 (a) 自然的,和 (b) 复合的。当这些主键作为外键迁移到下级表中时,逻辑上的关系完整性(与物理上的引用完整性不同,它是物理的,仅仅是 SQL 的一个特性)在下级表中实现表。

  • 例如。销售人员只能销售销售人员所雇用的经销商所拥有的经销商汽车。

  • 同样,客户只能从 SalesPerson 购买 DealerCars,而 DealerCars 由雇用该 SalesPerson 的经销商所有。

数据模型 • 关系失败

这是一个不了解关系键或关系完整性的人建立的数据模型,他只实现给定的键。我将包括其他错误,以便可以轻松获得与正确模型的比较。

  1. 关系键

    至少你的“教授”在数据中给出了唯一的键,这对层次结构有好处。
    在通常的灌输中,其中 1960 年代的 RFS 被教导为“关系”,“键”是物理的 Record IDs
    重点是,

    • 所有 RFS 解决方案(没有任何关系功能),
    • 以及任何半生不熟的关系解决方案(即理解和尝试的关系概念,但不是它们提供的关系键和关系完整性),

    有这个严重的错误。

    • 在这里,我使用了给定的键,但没有将它们建模为关系键,关系完整性丢失(是的,是的,我们仍然有参照完整性,达到建模的级别)。键被视为给定的,仅作为单列单元(从逻辑上讲,这意味着该目的所需的实际逻辑键的片段,即事实)。

    • 该模型对于 RFS 是正确的,并且仅限于该原始级别,但它作为关系数据模型是失败的。

    • SalesPerson 可以销售属于任何经销商的 DealerCar,即。不限于受雇为销售人员的经销商的汽车。哎呀。

    • 同样,客户可以从一个经销商和销售人员处购买汽车,其中不属于该经销商的 DealerCar;销售员。哎呀,糟透了。

  2. 汽车
    我已经将 Car 建模为 Independent,这是对 Car 的既定要求的奴隶建模。但它未能模拟此要求:

    汽车只能由一个经销商拥有,并且必须由经销商拥有才能进入数据库。
    正确建模后,Car 是属于 Dealer 的东西,所有 Car 属性(与 Ca​​r PK (VehicleNo) 为 1::1)都会移入 DealerCar。

  3. 颜色
    我已经按照要求显示了颜色,一个 CSV 列表,这是不正确的。

享受吧。


【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-18
    • 1970-01-01
    • 2014-01-09
    相关资源
    最近更新 更多