所謂的數據庫設計就是根據需求文檔的描述將需求轉成數據庫的存儲結構的過程.前端
在數據庫設計的流程上,咱們一般根據需求,畫出數據的ER圖.而後在經過ER圖生成數據庫的建庫腳本. (Entity Relational)sql
ER圖,所謂的ER圖就是數據庫關係圖數據庫
爲何咱們使用ER圖來實現數據庫設計的設計呢?express
1.可見便可得.使用ER圖能夠經過圖形的方式展現表與表直接的關係安全
2.能夠根據設置的數據庫,方便生成不一樣的數據庫的SQL建庫腳本eclipse
3.能夠快速的生成數據庫文檔數據庫設計
小結:所謂的數據庫設計,就是經過ER圖,根據需求給數據庫建表表結構!!!工具
軟件開發都是分別從頁面設計和數據庫設計開始的.性能
建立項目的數據庫是項目開發必須的階段.開發工具
數據庫設計的步驟是根據需求的描述:
第一步:標識表
第二步:標識表的字段
第三步:標識表與表之間的關係
所謂的標識表,就是根據需求將表建立!!
咱們在標識表的時候,能夠將表分爲實體表和業務表.
所謂的實體表:就是記錄需求中描述爲一個對象(名詞)的表.如:用戶,商品,訂單,管理員,角色等
所謂的業務表:就是記錄在需求中描述爲一個業務行爲(動詞)的表:收藏,關注,等 (大部分是中間表)
雖然沒有強制的規定先標識實體表仍是業務表,但咱們一般在標識表時會先標識實體表,再標識業務表.
由於業務表通常是用於標識實體表與另外一個實體的多對多的關係的.
標識字段,在數據庫設計中,儘可能符合數據庫設計的三大範式原則.
--三大範式,就是用於數據庫設計,標識字段的時候使用的!!!。
數據庫表設計三大範式最終解決的是數據冗餘問題
爲了創建冗餘較小、結構合理的數據庫,設計數據庫時必須遵循必定的規則。在關係型數據庫中這種規則就稱爲範式。範式是符合某一種設計要求的總結。要想設計一個結構合理的關係型數據庫,必須知足必定的範式。
在實際開發中最爲常見的設計範式有三個
第一範式是最基本的範式。若是數據庫表中的全部字段值都是不可分解的原子值,就說明該數據庫表知足了第一範式。
第一範式的合理遵循須要根據系統的實際需求來定。好比某些數據庫系統中須要用到「地址」這個屬性,原本直接將「地址」屬性設計成一個數據庫表的字段就行。可是若是系統常常會訪問「地址」屬性中的「城市」部分,那麼就非要將「地址」這個屬性從新拆分爲省份、城市、詳細地址等多個部分進行存儲,這樣在對地址中某一部分操做的時候將很是方便。這樣設計纔算知足了數據庫的第一範式,以下表所示。
上表所示的用戶信息遵循了第一範式的要求,這樣在對用戶使用城市進行分類的時候就很是方便,也提升了數據庫的性能。
非主鍵列必須依賴主鍵列存在
第二範式在第一範式的基礎之上更進一層。第二範式須要確保數據庫表中的每一列都和主鍵相關,而不能只與主鍵的某一部分相關(主要針對聯合主鍵而言)。也就是說在一個數據庫表中,一個表中只能保存一種數據,不能夠把多種數據保存在同一張數據庫表中。
好比要設計一個訂單信息表,由於訂單中可能會有多種商品,因此要將訂單編號和商品編號做爲數據庫表的聯合主鍵,以下表所示。
訂單信息表
這樣就產生一個問題:這個表中是以訂單編號和商品編號做爲聯合主鍵。這樣在該表中商品名稱、單位、商品價格等信息不與該表的主鍵相關,而僅僅是與商品編號相關。因此在這裏違反了第二範式的設計原則。
而若是把這個訂單信息表進行拆分,把商品信息分離到另外一個表中,把訂單項目表也分離到另外一個表中,就很是完美了。以下所示。
這樣設計,在很大程度上減少了數據庫的冗餘。若是要獲取訂單的商品信息,使用商品編號到商品信息表中查詢便可。
第三範式須要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。好比在設計一個訂單數據表的時候,能夠將客戶編號做爲一個外鍵和訂單表創建相應的關係。而不能夠在訂單表中添加關於客戶其它信息(好比姓名、所屬公司等)的字段。以下面這兩個表所示的設計就是一個知足第三範式的數據庫表。
這樣在查詢訂單信息的時候,就可使用客戶編號來引用客戶信息表中的記錄,也沒必要在訂單信息表中屢次輸入客戶信息的內容,減少了數據冗餘。
三大範式只是通常設計數據庫的基本理念,能夠創建冗餘較小、結構合理的數據庫。若是有特殊狀況,固然要特殊對待,數據庫設計最重要的是看需求跟性能,需求>性能>表結構(範式)。因此不能一味的去追求範式創建數據庫。
咱們不少系統都要記錄日誌.而日誌裏面,必需要包括用戶的信息.若是嚴格按照三大方式.日誌的用戶信息必須是從用戶表中得到,日誌天天都會出現巨量的數據。若是關聯用戶表查詢,整理日誌時會致使用戶表的訪問大大被拖慢。
因此,咱們會將用戶的信息直接寫在日誌表裏面。在日誌表中寫用戶的的信息,明顯違反了第二範式,基於查詢的性能的須要,通常日誌表的用戶信息是冗餘。
咱們在訂單中有一個商品的價格、商品名字。而這個商品的價格直接就是訂單的字段.並非商品表裏面商品的價格.明顯違反了第三範式.
但業務上,因爲訂單的商品的價格不能隨着着商家修改了商品價格而修改.因此像這種需求下,必需要給訂單表一個冗餘的商品價格字段。
表與表之間的關係包括有
數據庫表與表的關係,就是也需求描述的從屬關係。
問題:表與表之間的關係,是誰決定的?
答:需求決定的!!!
標識表,先標識實體表,在標識業務表
實體表(名詞,沒有行爲)
業務表(包括業務動做,通常就是一箇中間表)
標識字段,必需要求理解三大範式
爲何須要三大範式,避免數據的冗餘,致使數據的異常。
數據庫設計整體上要符合三大範式,可是基於業務需求和性能要求,有時候能夠有少量的冗餘。數據設計冗餘,設計者必需要說明緣由(項目需求須要)
標識表與表之間的關係
ERMaster 是集成到Eclipse開發工具的一個插件。
在工做區,右擊
右擊工做區,導出HTML
需求:設計一個學生成績管理系統
第一步:標識表,標識實體表。學生、學生身份、成績、老師
第二步:標識字段
第三步:標識表與表之間的關係
導出sql語句把邏輯名稱做爲註釋
sql
SET SESSION FOREIGN_KEY_CHECKS=0;
/* Drop Tables */
DROP TABLE IF EXISTS student_teacher; DROP TABLE IF EXISTS tb_info; DROP TABLE IF EXISTS tb_score; DROP TABLE IF EXISTS tb_student; DROP TABLE IF EXISTS tb_teacher;
/* Create Tables */
-- student_teacher CREATE TABLE student_teacher ( stu_id int NOT NULL COMMENT '學生id', teacher_id int NOT NULL COMMENT '主鍵' ) COMMENT = 'student_teacher';
-- 學生身份信息 CREATE TABLE tb_info ( stu_idcard varchar(50) COMMENT '身份證', stu_address varchar(100) COMMENT '地址', stu_phone varchar(50) COMMENT '電話', stu_email varchar(50) COMMENT '郵箱', stu_id int NOT NULL COMMENT '學生id' ) COMMENT = '學生身份信息';
-- 學生成績表 CREATE TABLE tb_score ( sc_id int NOT NULL AUTO_INCREMENT COMMENT '主鍵', sc_suject varchar(50) COMMENT '科目', sc_score float COMMENT '成績', stu_id int NOT NULL COMMENT '學生id', PRIMARY KEY (sc_id) ) COMMENT = '學生成績表';
-- 學生信息報 CREATE TABLE tb_student ( stu_id int NOT NULL AUTO_INCREMENT COMMENT '學生id', stu_name varchar(50) COMMENT '學生姓名', stu_account varchar(50) COMMENT '學生帳號', stu_pwd varchar(50) COMMENT '學生密碼', stu_salt varchar(100) COMMENT '密碼加密字段(鹽)', stu_status int DEFAULT 1 COMMENT '學生狀態 1 正常 0 鎖定', PRIMARY KEY (stu_id) ) COMMENT = '學生信息報';
-- 老師表 CREATE TABLE tb_teacher ( teacher_id int NOT NULL AUTO_INCREMENT COMMENT '主鍵', teacher_name varchar(50) COMMENT '姓名', teacher_account varchar(50) COMMENT '帳號', teacher_pwd varchar(50) COMMENT '密碼', teacher_phone varchar(50) COMMENT '老師電話', PRIMARY KEY (teacher_id) ) COMMENT = '老師表';
/* Create Foreign Keys */
ALTER TABLE student_teacher ADD FOREIGN KEY (stu_id) REFERENCES tb_student (stu_id) ON UPDATE RESTRICT ON DELETE RESTRICT ;
ALTER TABLE tb_info ADD FOREIGN KEY (stu_id) REFERENCES tb_student (stu_id) ON UPDATE RESTRICT ON DELETE RESTRICT ;
ALTER TABLE tb_score ADD FOREIGN KEY (stu_id) REFERENCES tb_student (stu_id) ON UPDATE RESTRICT ON DELETE RESTRICT ;
ALTER TABLE student_teacher ADD FOREIGN KEY (teacher_id) REFERENCES tb_teacher (teacher_id) ON UPDATE RESTRICT ON DELETE RESTRICT ;
|
Customer Relational Manager System (客戶關係管理系統)
客戶人員是一個不懂軟件設計的人,它但願有一個能夠作管理系統來管理他的員工.
描述以下:
系統的需求調研 1.每一個銷售人員只能查看本身的客戶. (銷售不能互相看客戶) 2.客戶是公司,有多個聯繫人 (客戶主體公司) 3.銷售能夠指定客戶給另外一個銷售人員跟進 (銷售人員能夠轉移客戶給另外銷售) 4.銷售人員離職時,能夠禁用不讓登陸 5.管理員能夠修改銷售人員的密碼 (後臺管理人員能夠管理全部信息) 6.銷售人員能夠設置重點跟進客戶,而且能夠說明重點跟進客戶的緣由. 7.銷售人員能夠屢次跟進同一個客戶(騷擾) |
功能列表給到客戶人員。給到開發人員,跟進需求文檔設計數據庫。
前端功能(銷售人員的功能) |
1.客戶管理 |
2.聯繫人管理 |
|
3.轉移客戶 |
|
4.跟進客戶 |
|
5.標記重點客戶 |
|
後臺管理(管理員管理 RBAC) |
1.客戶管理 (全局) |
2.聯繫人管理(全局) |
|
3.管理員管理 |
|
4.角色管理 |
|
5.權限管理 |
根據功能列表與客戶調研報告(需求文檔),設計數據數據庫。
第一步:RBAC系統的設計
Role Based Access Control (基於角色的權限控制系統);就是根據不一樣的用戶,根據用於所屬的角色不一樣而登陸的界面就不一樣。
需求:一個管理員只有一個角色(單角色的設計),一個角色能夠有多個管理員
一個就是能夠有多個權限,一個權限也能夠有在多個角色角色。
第二步:業務系統的設計(CRM)
需求:
PowerDesigner是一個專業的數據庫設計軟件。如今市場主流的數據庫設計工具!!
--不要建立邏輯ER圖,邏輯ER圖只能看,不能生成數據腳本。
問題:設計表的時候,發現沒有ID自增加選項
答:是由於默認沒有指定Mysql數據庫。因此須要設計爲MySQL數據庫。
--修改後,發現多個一個Identity選項
設計圖以下:
--設置導出的路徑
--生成的SQL腳本
/*==============================================================*/ /* DBMS name: MySQL 5.0 */ /* Created on: 2019/6/16 23:29:00 */ /*==============================================================*/
drop table if exists tb_user;
/*==============================================================*/ /* Table: tb_user */ /*==============================================================*/ create table tb_user ( user_id int not null auto_increment comment '用戶id', user_name varchar(50) comment '用戶姓名', user_account varchar(50) comment '用戶帳號', user_password varchar(50) comment '密碼', user_status int comment '1 可用,0 鎖定', primary key (user_id) );
alter table tb_user comment '這是用戶表,存儲用戶信息';
|
問題:如何顯示註釋字段
RBAC (Role Based Access Control) 基於角色的權限系統。
RBAC系統能夠實現根據不一樣的用戶,顯示的權限(菜單-功能)就不同。
需求:
用戶與角色的關係:N :1
角色與權限的關係:N :N
/*==============================================================*/ /* DBMS name: MySQL 5.0 */ /* Created on: 2019/6/17 15:27:54 */ /*==============================================================*/
drop table if exists tb_permission;
drop table if exists tb_role;
drop table if exists tb_role_permission;
drop table if exists tb_user;
/*==============================================================*/ /* Table: tb_permission */ /*==============================================================*/ create table tb_permission ( permission_id int not null auto_increment comment '權限id', permission_name varchar(50) comment '權限名稱', permission_url varchar(150) comment '權限url地址', perimssion_expression varchar(100) comment '權限表達式', permission_type int comment '是不是菜單權限 0 普通權限 1 菜單權限', permission_parent_id int comment '權限父id', permission_sorting int comment '權限菜單時候排序升序', primary key (permission_id) );
/*==============================================================*/ /* Table: tb_role */ /*==============================================================*/ create table tb_role ( role_id int not null auto_increment comment '角色id', role_name varhcar(50) comment '角色名稱', user_desc varchar(500) comment '角色描述', primary key (role_id) );
/*==============================================================*/ /* Table: tb_role_permission */ /*==============================================================*/ create table tb_role_permission ( role_id int comment '角色id', permission_id int comment '權限id', role_permission_id int not null auto_increment comment '主鍵', primary key (role_permission_id) );
/*==============================================================*/ /* Table: tb_user */ /*==============================================================*/ create table tb_user ( user_id int not null auto_increment comment '用戶id', user_name varchar(50) comment '名稱', user_account varchar(50) comment '帳號', user_pwd varchar(50) comment '密碼', user_salt varchar(50) comment '鹽(密碼加密)', user_desc varchar(500) comment '描述', user_status int comment '狀態 1 可用,0鎖定 ,2 ,刪除', role_id int comment '角色id', primary key (user_id) );
alter table tb_role_permission add constraint FK_Reference_2 foreign key (role_id) references tb_role (role_id) on delete restrict on update restrict;
alter table tb_role_permission add constraint FK_Reference_3 foreign key (permission_id) references tb_permission (permission_id) on delete restrict on update restrict;
alter table tb_user add constraint FK_Reference_1 foreign key (role_id) references tb_role (role_id) on delete restrict on update restrict; |