数据类型(整型、浮点数、字符串、时间和日期)、切分(水平、垂直)
1. 數據類型
1.1 整型
TINYINT, SMALLINT, MEDIUMINT, INT, BIGINT 分別使用 8, 16, 24, 32, 64 位存儲空間,一般情況下越小的列越好。
INT(11) 中的數字只是規定了交互工具顯示字符的個數,對于存儲和計算來說是沒有意義的。
1.2 浮點數
FLOAT 和 DOUBLE 為浮點類型,DECIMAL 為高精度小數類型。CPU 原生支持浮點運算,但是不支持 DECIMAl 類型的計算,因此 DECIMAL 的計算比浮點類型需要更高的代價。
FLOAT、DOUBLE 和 DECIMAL 都可以指定列寬,例如 DECIMAL(18, 9) 表示總共18 位,取 9 位存儲小數部分,剩下 9 位存儲整數部分。
1.3 字符串
主要有 CHAR 和 VARCHAR 兩種類型,一種是定長的,一種是變長的。
- VARCHAR 這種變長類型能夠節省空間,因為只需要存儲必要的內容。但是在執行UPDATE 時可能會使行變得比原來長,當超出一個頁所能容納的大小時,就要執行額外的操作。MyISAM 會將行拆成不同的片段存儲,而 InnoDB 則需要分裂頁來使行放進頁內。
- VARCHAR 會保留字符串末尾的空格,而 CHAR 會刪除。
1.4?時間和日期
MySQL 提供了兩種相似的日期時間類型:DATETIME 和 TIMESTAMP。
1.4.1 DATETIME
能夠保存從 1001 年到 9999 年的日期和時間,精度為秒,使用 8 字節的存儲空間。
它與時區無關。
默認情況下,MySQL 以一種可排序的、無歧義的格式顯示 DATETIME 值,例如“2008-01-16 22:37:08”,這是 ANSI 標準定義的日期和時間表示方法。
1.4.2?TIMESTAMP
和 UNIX 時間戳相同,保存從 1970 年 1 月 1 日午夜(格林威治時間) 以來的秒數,使用 4 個字節,只能表示從 1970 年 到 2038 年。
它和時區有關,也就是說一個時間戳在不同的時區所代表的具體時間是不同的。
MySQL 提供了 FROM_UNIXTIME() 函數把 UNIX 時間戳轉換為日期,并提供了UNIX_TIMESTAMP() 函數把日期轉換為 UNIX 時間戳。
默認情況下,如果插入時沒有指定 TIMESTAMP 列的值,會將這個值設置為當前時間。
應該盡量使用 TIMESTAMP,因為它比 DATETIME 空間效率更高。
2. 切分
2.1 水平切分
水平切分又稱為 Sharding,它是將同一個表中的記錄拆分到多個結構相同的表中。
當一個表的數據不斷增多時,Sharding 是必然的選擇,它可以將數據分布到集群的不同節點上,從而緩存單個數據庫的壓力。
2.2?垂直切分
垂直切分是將一張表按列切分成多個表,通常是按照列的關系密集程度進行切分,也可以利用垂直切分將經常被使用的列和不經常被使用的列切分到不同的表中。
在數據庫的層面使用垂直切分將按數據庫中表的密集程度部署到不同的庫中,例如將原來的電商數據庫垂直切分成商品數據庫、用戶數據庫等。
2.3 Sharding 策略
- 哈希取模:hash(key) % NUM_DB
- 范圍:可以是 ID 范圍也可以是時間范圍
- 映射表:使用單獨的一個數據庫來存儲映射關系
2.4 Sharding 存在的問題及解決方案
2.4.1 事務問題
使用分布式事務來解決,比如 XA 接口。
2.4.2 鏈接
可以將原來的 JOIN 分解成多個單表查詢,然后在用戶程序中進行 JOIN。
2.4.3 ID 唯一性
- 使用全局唯一 ID:GUID
- 為每個分片指定一個 ID 范圍
- 分布式 ID 生成器 (如 Twitter 的 Snowflake 算法)
?
總結
以上是生活随笔為你收集整理的数据类型(整型、浮点数、字符串、时间和日期)、切分(水平、垂直)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 查询性能优化(使用 Explain 进行
- 下一篇: 复制(主从复制、读写分离)