前言: sql
在咱們項目開發中,數據庫及表的設計能夠說是很是重要,我遇到過不少庫表設計比較雜亂的項目,像表名、字段名命名混亂、字段類型設計混亂等等,此類數據庫後續極難維護與拓展。我一直相信只有優秀的庫表設計才能發揮出MySQL最大的性能,前面有篇文章也分享了數據庫的使用規範,本篇文章主要講幾個庫表設計的小技巧,但願對你們有所啓發。數據庫
整型字段類型包含 tinyint、smallint、mediumint、int、bigint 五種,佔用空間大小及存儲範圍以下圖所示:函數
存儲字節越小,佔用空間越小。因此本着最小化存儲的原則,咱們要儘可能選擇合適的整型,下面給出幾個常見案例及選擇建議。性能
下面給出建表語句示範:測試
CREATE TABLE `tb_int` ( `increment_id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵', `stu_age` tinyint unsigned NOT NULL COMMENT '學生年齡', `is_deleted` tinyint unsigned DEFAULT '0' COMMENT '0:未刪除 1:刪除', `col1` bigint NOT NULL COMMENT 'bigint字段', PRIMARY KEY (`increment_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='int測試表';
時間字段類型能夠選用datetime和timestamp,下面用一張表展現下兩者的區別:spa
timestamp翻譯爲漢語即"時間戳",它是當前時間到 Unix元年(1970 年 1 月 1 日 0 時 0 分 0 秒)的秒數,佔用4個字節,並且是以UTC的格式儲存,它會自動檢索當前時區並進行轉換。datetime以8個字節儲存,不會進行時區的檢索。也就是說,對於timestamp來講,若是儲存時的時區和檢索時的時區不同,那麼拿出來的數據也不同。對於datetime來講,存什麼拿到的就是什麼。下面給出幾個常見案例及選擇建議。翻譯
若是timestamp字段常常用於查詢,咱們還可使用MySQL內置的函數FROM_UNIXTIME()、UNIX_TIMESTAMP(),將日期和時間戳數字來回轉換,轉換後能夠用 INT UNSIGNED 存儲時間,數字是連續的,佔用空間更小,而且可使用索引提高查詢性能。下面給出示範建表語句及時間戳相關轉換SQL:設計
CREATE TABLE `tb_time` ( `increment_id` int unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵', `col1` datetime NOT NULL DEFAULT '2020-10-01 00:00:00' COMMENT '到期時間', `unix_createtime` int unsigned NOT NULL COMMENT '建立時間戳', `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間', `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改時間', PRIMARY KEY (`increment_id`), KEY `idx_unix_createtime` (`unix_createtime`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='time測試表'; # 插入數據 insert into tb_time (unix_createtime,create_time) values (UNIX_TIMESTAMP(now()),now()); # 時間戳數字與時間相互轉換 select UNIX_TIMESTAMP('2020-05-06 00:00:00') select FROM_UNIXTIME(1588694400)
IP值通常使用char或varchar進行存儲,可是當進行查找和統計時,字符類型不是很高效。MySQL數據庫內置了兩個IP相關的函數INET_ATON()、INET_NTOA(),能夠實現 IP 地址和整數類型的轉換。轉換後使用能夠INT UNSIGNED 來存儲IP,轉換後的數字是連續的,提升了查詢性能,佔用空間更小。unix
CREATE TABLE `tb_ip` ( `increment_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增主鍵', `name` varchar(100) NOT NULL COMMENT '姓名', `inet_ip` int(10) unsigned NOT NULL COMMENT 'IP', PRIMARY KEY (`increment_id`), KEY `idx_inet_ip` (`inet_ip`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='ip測試表'; # 插入數據 insert into `tb_ip` (`name`,`inet_ip`) values ('wang',INET_ATON('192.168.0.1')),('lisi',INET_ATON('192.168.0.2')); # 相互轉換 select INET_ATON('192.168.0.1'); select INET_NTOA(3232235521);
總結: code
本篇文章分享了幾個庫表設計及字段類型選取的建議。這些案例都是經常見到的場景,對於int類型及時間類型的選取,本文也根據常見場景給出相關建議,但願你們讀完這篇文章有所收穫。其實庫表設計是件複雜的事情,須要在項目前期多方人員共同規劃討論。仍是那句話,只有優秀的庫表設計才能發揮出MySQL最大的性能。
本文由博客一文多發平臺 OpenWrite 發佈!