范式

第一范式

  • 第一范式要求:所有的字段都是基本数据字段,不可进一步拆分。

第二范式

  • 第二范式:在满足第一范式的基础上,还要满足数据表里的每一条数据记录,都是可唯一标识的。而且所有字段,都必须完全依赖主键,不能只依赖主键的一部分。

MySQL 模型怎么用的 mysqler模型_sql


并且 barcode”是有可能存在重复的, 所有的字段都不能唯一标识表里 的记录。这个时候,我们必须给这个表加上一个主键“itemnumber“。 然后分别拆分为下面这三个表 :

MySQL 模型怎么用的 mysqler模型_MySQL 模型怎么用的_02


MySQL 模型怎么用的 mysqler模型_sql_03

第三范式

  • 第三范式:要求数据表在满足第二范式的基础上,不能包含那些可以由非主键字段派生出来 的字段,或者说,不能存在依赖于非主键字段的字段。
    上面 , 字段“suppliername”依赖于非主键字段“supplierid”。 因此需要改为

业务优先原则

  • 所谓的业务优先原则,就是指一切以业务需求为主,技术服务于业务。完全按照理论的设计不一定就是最优,还要根据实际情况来决定。
  • quantity * importprice = importvalue,看起来“importvalue”似乎是冗余字段, 但并不会导致数据不一致。可是,如果我们把这个字段取消,是会影响业务的。
  • 如果不保留“importvalue”字段,只有“importprice”和“quantity”的 话,经过四舍五入,会产生较大的误差。这样日积月累,最终会导致查询结果出现较大偏 差,影响系统的可靠性,如果删除的话只会得不偿失,系统的成本都会提高。

范式总结

  • 第一范式:数据表中所有字段都是不可拆分的基本数据项。
  • 第二范式:在满足第一范式的基础上,数据表中所有非主键字段,必须完全依赖全部主键字段。
  • 第三范式:在满足第二范式的基础上,数据表中不能存在可以被其他非主键字段派生出来的字段,或者说,不能存在依赖于非主键字段的字段。
  • 遵循业务优先的原则,首先满足业务需求,在这个前提下,再尽量减少冗余。

ER模型

  • ER 模型也叫作实体关系模型,是用来描述现实生活 中客观存在的事物、事物的属性,以及事物之间关系的一种数据模型。在开发基于数据库 的信息系统的设计阶段,通常使用 ER 模型来描述信息需求和信息特性,帮助我们理清业 务逻辑,从而设计出优秀的数据库。

三个要素

  • 实体,可以看做是数据对象,往往对应于现实生活中的真实存在的个体。(用矩形表示), 强实体是指不依赖于其他实体的实体;弱实体是指对另一个实体有很强 的依赖关系的实体。
  • 属性,则是指实体的特性。
  • 关系,则是指实体之间的联系。
  • 可以独立存在的是实体,不可 再分的是属性。也就是说,属性不需要进一步描述,不能包含其他属性。
  • 关系的3个类型 :
  • 1 对 1:指实体之间的关系是一一对应的 。
  • 1 对多:指一边的实体通过关系,可以对应多个另外一边的实体。
  • 多对多:指关系两边的实体都可以通过关系对应多个对方的实体。
  • ER模型 是一个建模的过程 , 需要重视其中的思路 !! 下图 1表示关系只有一个 , NMQP 表示多
  • 这里我是用粗框矩形表示弱实体,用粗框菱形,表示弱实体与它依赖的强实体之间的关系。
  • 通过外键来表达 1 对多的关系

把元素转换为 表

-- 强实体 
-- 供货商表(demo.supplier)
CREATE TABLE demo.supplier
 (
 -- 我们给它添加一个与业务无关的字段“supplierid”为主键,并且设置自增约束。
 supplierid INT PRIMARY KEY AUTO_INCREMENT,
 suppliername TEXT,
 address TEXT,
 phone TEXT
 );

-- 商品表(demo.goodsmaster)
CREATE TABLE demo.goodsmaster
 (
 --我们给商品信息表添加一个与业务无关的字段“itemnumber”为主键,采用手动赋值的方式,原因是可能存在多个门店录入新品,导致冲突的情况
 itemnumber INT PRIMARY KEY,
 barcode TEXT,
 goodsname TEXT,
 specification TEXT,
 unit TEXT,
 salesprice DECIMAL(10,2)
 );
-- 门店表(demo.branch)

 CREATE TABLE demo.branch
 (
 -- 增加一个与业务无关的字段为主键,并且设置自增约束
 branchid INT PRIMARY KEY AUTO_INCREMENT,
 branchno TEXT,
 branchname TEXT,
 address TEXT,
 phone TEXT,
 contacter TEXT
 );
-- 弱实体 

-- 仓库表(demo.stock)

 CREATE TABLE demo.stock
 (
 --添加与业务无关的自增约束字段为主键
 stockid INT PRIMARY KEY AUTO_INCREMENT,
 -- 仓库是弱实体,依赖于强实体门店表,所以要把门店表的主键字段包括进来,作为与门店表关联的外键
 branchid INT NOT NULL,
 stockno TEXT NOT NULL,
 stockname TEXT NOT NULL,
 -- 设置外键约束,与门店表关联
 CONSTRAINT fk_stock_branch FOREIGN KEY (branchid) REFERENCES branch (branchid)
- );


 -- 收银款台表(demo.cashier)
mysql> CREATE TABLE demo.stock
-> (
-> --添加与业务无关的自增约束字段为主键
-> stockid INT PRIMARY KEY AUTO_INCREMENT,
-> -- 仓库是弱实体,依赖于强实体门店表,所以要把门店表的主键字段包括进来,作为与门店表关联的外键
-> branchid INT NOT NULL,
-> stockno TEXT NOT NULL,
-> stockname TEXT NOT NULL,
-> -- 设置外键约束,与门店表关联
-> CONSTRAINT fk_stock_branch FOREIGN KEY (branchid) REFERENCES branch (branchid)
-> );
 -- 员工表(demo.operator)
 
mysql> CREATE TABLE demo.operator
-> (
-> -- 添加与业务无关的自增字段为主键
-> operatorid INT PRIMARY KEY AUTO_INCREMENT,
-> -- 员工是弱实体,依赖于强实体门店表,所以要把门店表的主键字段包括进来,所为与门店表关联的外键
-> branchid INT NOT NULL,
-> workno TEXT NOT NULL,
-> operatorname TEXT NOT NULL,
-> phone TEXT,
-> address TEXT,
-> pid TEXT,
-> duty TEXT,
-> -- 设置外键约束,与门店表关联
-> CONSTRAINT fk_operator_branch FOREIGN KEY (branchid) REFERENCES branch (branchid)
-> );

-- 会员表(demo.membermaster)


mysql> CREATE TABLE demo.membermaster
-> (
-> -- 添加与业务无关的自增字段为主键
-> memberid INT PRIMARY KEY,
-> -- 会员是弱实体,依赖于强实体门店表,所以要把门店表的主键字段包括进来,所为与门店表关联的外键
-> branchid INT NOT NULL,
-> cardno TEXT NOT NULL,
-> membername TEXT,
-> address TEXT,
-> phone TEXT,
-> pid TEXT,
-> -- 设置默认约束,积分默认为0
-> memberpoints DECIMAL(10,1) NOT NULL DEFAULT 0,
-> -- 设置默认约束,储值默认为0
-> memberdeposit DECIMAL(10,2) NOT NULL DEFAULT 0,
-> -- 设置外键约束,与门店表关联
-> CONSTRAINT fk_member_branch FOREIGN KEY (branchid) REFERENCES branch (branchid)
-> );



--多对多的关系转换成一个数据表
 -- 数据表设计的第三范式的要求和业务优先的原则
 --进货单表拆分成 进货单头表和进货单明细表
CREATE TABLE demo.importhead
(
importid INT PRIMARY KEY,   -- 添加与业务无关的字段为主键 
listnumber TEXT NOT NULL, -- NOT NULL 非空约束
supplierid INT NOT NULL,    -- 供货商表的主键,反映了参与进货关系的供货商信息
stockid INT NOT NULL,       -- 仓库表的主键,反映了参与进货关系的仓库信息
operatorid INT NOT NULL,    -- 员工表的主键,反映了参与进货关系的员工信息
recordingdate DATETIME NOT NULL,
totalquantity DECIMAL(10,3) NOT NULL DEFAULT 0,
totalvalue DECIMAL(10,3) NOT NULL DEFAULT 0,
 -- 通过外键来表达 1 对多的关系d
CONSTRAINT fk_importhead_supplier FOREIGN KEY (supplierid) REFERENCES supplier (supplierid),
CONSTRAINT fk_transactionhead_member FOREIGN KEY (memberid) REFERENCES membermaster (memberid),
CONSTRAINT fk_importhead_operator FOREIGN KEY (operatorid) REFERENCES operator (operatorid)
);
CREATE TABLE demo.importdetails
(
importid INT,
itemnumber INT,              -- 商品表的主键,反映了参与进货关系的商品信息
importquantity DECIMAL(10,3) NOT NULL DEFAULT 0,
importprice DECIMAL(10,2) NOT NULL DEFAULT 0,
importvalue DECIMAL(10,2) NOT NULL DEFAULT 0,
PRIMARY KEY (importid,itemnumber),
CONSTRAINT fk_importdetails_goodsmaster FOREIGN KEY (itemnumber) REFERENCES goodsmaster (itemnumber)
);
 
-- 流水单表拆分成流水单头表和流水单明细表
CREATE TABLE demo.transactionhead
(
transactionid INT PRIMARY KEY,   -- 添加与业务无关的字段为主键
transactionno TEXT NOT NULL,
cashierid INT NOT NULL,          -- 收款机表的主键,反映了参与零售关系的收款机信息
memberid INT,                    -- 会员表的主键,反映了参与零售关系的会员的信息
operatorid INT NOT NULL,         -- 员工表的主键,反映了参与零售关系的员工信息
transdate DATETIME NOT NULL,
-- 通过外键来表达 1 对多的关系
CONSTRAINT fk_transactionhead_cashier FOREIGN KEY (cashierid) REFERENCES cashier (cashierid),
CONSTRAINT fk_transactionhead_member FOREIGN KEY (memberid) REFERENCES member (memberid),
CONSTRAINT fk_transactionhead_operator FOREIGN KEY (operatorid) REFERENCES operator (operatorid)
);
CREATE TABLE demo.transactiondetails
(
transactionid INT,
itemnumber INT,                 -- 商品表的主键,反映了参与零售关系的商品信息
quantity DECIMAL(10,3) NOT NULL DEFAULT 0,
price DECIMAL(10,2) NOT NULL DEFAULT 0,
salesvalue DECIMAL(10,2) NOT NULL DEFAULT 0,
PRIMARY KEY (transactionid,itemnumber),
CONSTRAINT fk_transactiondetails_goodsmaster FOREIGN KEY (itemnumber) REFERENCES goodsmaster (itemnumber)
);