MySQL 表設計

來源:互聯網
上載者:User

標籤:大致   缺點   code   學生   rem   抽取   一對一   執行   個數   

0、這個部落格中一部分內容是Deolin的個人觀點和習慣。

 

1、把SET del_flag = 1 稱為“移除”(remove),

把DELETE FROM table 稱為“擦除”(expunge),

至於“刪除”(delete)、“取消”(cancel),則更像個業務層而不是持久層的概念。

 

2、資料表可以分為資訊表,關聯表,字典表。

 

3、資訊表反映的是資料資訊,“資料為王”主要指的就是這類表裡的資料。

資訊表應該有以下欄位

id int 這條資料的主鍵,預設長度,無符號,自增,前位補零。由於del_flag的存在,所以業務上的欄位做主鍵便不再合適,因為新插入的資料很有可能與被移除的資料發生主鍵重複,所以需要一個毫無業務意義的主鍵

insert_time datetime 這條資料第一次執行insert文的時間,不可為空。

update_time datetime 這條資料每次執行update文的時間,可以為空白(如果從為被update過,那就應該是空的)。

del_flag tinyint(1) 這條資料是否被移除,不可為空,預設為0。由於資訊表裡的資料往往比較重要,所以應該禁止擦除,使用移除。而“有del_flag欄位”和“使用移除”兩件事情應該同時出現,或同時不出現

 

資訊表可以有以下欄位,但不是“應該有”

insert_id int 插入這條資料的業務上的插入者id,代表的是某一個資訊表的主鍵(user表之類的)。

insert_table char(64) 如果業務上不只一類插入者,那麼需要指定是那個資訊表。長度定為64,因為表名最長64個字元。

update_id int 與insert_id同理。

update_table char(64) 與insert_table同理。

 

如果是整個項目在業務上沒有登入行為,或是管理員在db上插入/修改的,那麼些欄位只能為空白了,這也是這些欄位不算“應該有”的原因了。

 

一個資訊表的樣本可能是這樣的

CREATE TABLE `person` (  `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,  `name` varchar(20) NOT NULL,  `sex` tinyint(1) DEFAULT NULL,  `birthday` date DEFAULT NULL,  `father_age` int(3) DEFAULT NULL, #這個欄位可能非常奇怪,但Deolin只是希望能在樣本裡有至少一個int欄位,並且最好不是age(age跟birthday一起出現的話顯得更加奇怪)  `tuition` decimal(8,2) DEFAULT NULL,  `payment_time` datetime DEFAULT NULL,  `vip_flag` tinyint(1) DEFAULT NULL,  `insert_time` datetime NOT NULL,  `update_time` datetime DEFAULT NULL,  `del_flag` tinyint(1) NOT NULL DEFAULT ‘0‘,  PRIMARY KEY (`id`))

 

4、關聯表反映的是兩張資訊表之間多對多的關係,例如學生表與課程表之間的關係

除了主鍵,關聯表應該有像資訊表那樣的基礎欄位。

至於主鍵,它的設計有兩種方式

第一種

放棄主鍵id,而是使用被關聯表各自的id作為雙主鍵(如student_id, lesson_id),

這種方式優點是直觀,一眼就能看出是關聯表,而且關聯關係絕對不會重複。

有個缺點,del_flag和移除操作不能做了,因為會發生主鍵重複,所以只能擦除。

 

第二種

使用主鍵id,優缺點與第一種方式正好相反。

主要適用於兩種場合,一是整個項目有比較強的資料採礦和分析目地的,即便是關聯關係也要保留下來,

二是關聯關係產生時,會出現一些業務欄位(如學生選的課,會有成績,那麼成績欄位不應該放在student或lesson中,而是應該放在關聯表裡)

 

5、字典表反映的是為項目本身提供的各種資料,是對項目擴充性的補充,

(如JSP中option標籤的每一個value屬性,如某個表‘kind‘之類欄位的值解釋,如一些配置屬性),資料量不會很大,

基本上,資料是開發人員錄入,項目不會對它有增、改、移除、擦除操作,只有查詢操作,一個不是特別大的項目只需要一張字典表。

一般只有以下欄位

key varchar(255) 主鍵,字典的索引

value varchar(255)  字典的值

group varchar(255) 用來表示key屬於那一類,可以為空白

sort int 用來表示key在自己所在group的順序,可以為空白

disable tinyint(1) 用來表示這條資料是否被失效,不可為空,預設0

 

6、資訊表之間一對一的關係,設計成兩張表的id欄位一致

例如`person`表示例中,每個人都有“學生”和“子女”兩個不同模組的屬性,可以將它們分別抽取出來

CREATE TABLE `person` (  `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,  `name` varchar(20) NOT NULL,  `sex` tinyint(1) DEFAULT NULL,  `birthday` date DEFAULT NULL,  `vip_flag` tinyint(1) DEFAULT NULL,  `insert_time` datetime NOT NULL,  `update_time` datetime DEFAULT NULL,  `del_flag` tinyint(1) NOT NULL DEFAULT ‘0‘,  PRIMARY KEY (`id`)  #與其他兩張表的id形成邏輯外鍵)CREATE TABLE `student` (  `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,  `tuition` decimal(8,2) DEFAULT NULL,  `payment_time` datetime DEFAULT NULL,  `insert_time` datetime NOT NULL,  `update_time` datetime DEFAULT NULL,  `del_flag` tinyint(1) NOT NULL DEFAULT ‘0‘,  PRIMARY KEY (`id`)  #與其他兩張表的id形成邏輯外鍵)CREATE TABLE `child` (  `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,  `father_age` int(3) DEFAULT NULL,  `father_job` int(3) DEFAULT NULL,    `mother_age` int(3) DEFAULT NULL,      `mother_job` int(3) DEFAULT NULL,    `insert_time` datetime NOT NULL,  `update_time` datetime DEFAULT NULL,  `del_flag` tinyint(1) NOT NULL DEFAULT ‘0‘,  PRIMARY KEY (`id`)  #與其他兩張表的id形成邏輯外鍵)

 

7、資訊表之間一對多的關係,在“多”的表中追加一個 `for_表名` 欄位(如果其他欄位中有單詞for,有時候也會設計成`表名_id`)

例如,一家學校當前有多個學生,一個學生當前只能屬於一個學校

CREATE TABLE `school` (  `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,  `address` varchar(200) DEFAULT NULL,  `insert_time` datetime NOT NULL,  `update_time` datetime DEFAULT NULL,  `del_flag` tinyint(1) NOT NULL DEFAULT ‘0‘,  PRIMARY KEY (`id`))CREATE TABLE `student` (  `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,  `for_school` int(11) NOT NULL DEFAULT ‘0‘,  #與school.id形成邏輯外鍵  `name` varchar(20) DEFAULT NULL,  `insert_time` datetime NOT NULL,  `update_time` datetime DEFAULT NULL,  `del_flag` tinyint(1) NOT NULL DEFAULT ‘0‘,  PRIMARY KEY (`id`))

 

8、關聯表的命名,一般是兩張“多”的表的表名用2連結

例如一個學生選擇多門課程,一門課程供多名學生選擇

CREATE TABLE `selectable_lesson` (  `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT,    #省略PRIMARY KEY (`id`))
CREATE TABLE `normal_student` ( `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT, #省略PRIMARY KEY (`id`))
CREATE TABLE `normal_student2selectable_lesson` ( #意為normal student to selectable lesson `id` int(11) unsigned zerofill NOT NULL AUTO_INCREMENT, `for_normal_student` int(11) NOT NULL DEFAULT ‘0‘, #與normal_student.id形成邏輯外鍵 `for_selectable_lesson` int(11) NOT NULL DEFAULT ‘0‘, #與selectable_lesson.id形成邏輯外鍵 `score` int(3) DEFAULT NULL, `insert_time` datetime NOT NULL, `update_time` datetime DEFAULT NULL, `del_flag` tinyint(1) NOT NULL DEFAULT ‘0‘, PRIMARY KEY (`id`))

 

9、資訊表的中欄位名中不出現表名,

如不採用user.username,而是採用user.name

 

11、資訊表中涉及到“屬於什麼類型”、“是哪種分類”概念的欄位,用`kind`表示,如user.kind

涉及到以上概念資訊表,用諸如`food_type`來表示。

 

10、類型

字串長度不變的用char(n),

字串能大致確定範圍的用varchar(n),

字串範圍超過65532的用text,

年齡之類的欄位通常用int(n),

上限不定的個數類欄位通常用int預設,即最長11,

更長時用bigint,

日期用date,

日期+時間用datetime,

時間用time,

區類別欄位(如“性別”,“直轄市”等)用tiny(1)(並在Java代碼中定義好規約),

是/否類欄位用tiny(1),

價格類欄位用decimal(8,2),-99,999,999.99 ~ 99,999,999.99,

電話/手機用varchar(20),

`id`用int,`insert_time`和`update_time`用datetime,`del_flag`用10。

MySQL 表設計

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.