MySQL 如何儲存長度很長的資料欄位
最近,在工作中遇到了MySQL中如何儲存長度較長的欄位型別問題,於是花了一週多的時間抽空學習了一下,並且記錄下來。
MySQL大致的邏輯儲存結構在這篇文章中有介紹,做為基本概念:InnoDB 邏輯儲存結構
注:文中所指的大資料指的是長度較長的資料欄位,包括varchar/varbinay/text/blob。
Compact行格式
我們首先來看一下行格式為Compact是如何儲存大資料的:
mysql> select version(); +-----------+ | version() | +-----------+ | 5.1.73 | +-----------+ 1 row in set (0.01 sec) mysql> show table status like 'row'\G; *************************** 1. row *************************** Name: row Engine: InnoDB Version: 10 Row_format: Compact Rows: 1 Avg_row_length: 81920 Data_length: 81920 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2017-01-04 21:46:02 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec)
我們建立一張測試表,插入資料:
CREATE TABLE `row` ( `content` varchar(65532) NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=latin1 mysql> insert into row(content) select repeat('a',65532); Query OK, 1 row affected (0.03 sec) Records: 1 Duplicates: 0 Warnings: 0
我們使用py_innodb_page_info.py工具來檢視錶中的頁分佈:
[root@localhost mysql]# python py_innodb_page_info.py -v com/row.ibd page offset 00000000, page type <File Space Header> page offset 00000001, page type <Insert Buffer Bitmap> page offset 00000002, page type <File Segment inode> page offset 00000003, page type <B-tree Node>, page level <0000> page offset 00000004, page type <Uncompressed BLOB Page> page offset 00000005, page type <Uncompressed BLOB Page> page offset 00000006, page type <Uncompressed BLOB Page> page offset 00000007, page type <Uncompressed BLOB Page> Total number of page: 8: Insert Buffer Bitmap: 1 Uncompressed BLOB Page: 4 File Space Header: 1 B-tree Node: 1 File Segment inode: 1
可以看出,第4頁的<B-tree Node>, page level <0000>
格式為資料頁,存放著MySQL的行資料。<Uncompressed BLOB Page>
可以理解為MySQL存放大資料的地方,暫且叫作外部儲存頁。Compact格式沒有將大資料全部放在資料頁中,而是將一部分資料放在了外部儲存頁中。那麼,是全部資料在外部儲存頁中,還是一部分資料。假如是一部分資料,這一部分是多少呢?
我們使用hexdump -Cv row.ibd
檢視一下資料頁<B-tree Node>, page level <0000>
,也就是第4頁:
3073 0000c000 8c 25 17 57 00 00 00 03 ff ff ff ff ff ff ff ff |.%.W....????????| 3074 0000c010 00 00 00 00 00 07 3a b8 45 bf 00 00 00 00 00 00 |......:?E?......| 3075 0000c020 00 00 00 00 00 02 00 02 03 a6 80 03 00 00 00 00 |.........?......| 3076 0000c030 00 7f 00 05 00 00 00 01 00 00 00 00 00 00 00 00 |................| 3077 0000c040 00 00 00 00 00 00 00 00 00 13 00 00 00 02 00 00 |................| 3078 0000c050 00 02 00 f2 00 00 00 02 00 00 00 02 00 32 01 00 |...?.........2..| 3079 0000c060 02 00 1c 69 6e 66 69 6d 75 6d 00 02 00 0b 00 00 |...infimum......| 3080 0000c070 73 75 70 72 65 6d 75 6d 14 c3 00 00 10 ff f1 00 |supremum.?...??.| 3081 0000c080 00 00 00 04 03 00 00 00 00 13 12 80 00 00 00 2d |...............-| 3082 0000c090 01 10 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |..aaaaaaaaaaaaaa| 3083 0000c0a0 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| 3084 0000c0b0 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| 3085 0000c0c0 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| .... .... 3128 0000c370 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| 3129 0000c380 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| 3130 0000c390 61 61 00 00 00 02 00 00 00 04 00 00 00 26 00 00 |aa...........&..| 3131 0000c3a0 00 00 00 00 fc fc 00 00 00 00 00 00 00 00 00 00 |....??..........| 3132 0000c3b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 3133 0000c3c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 3134 0000c3d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ... ... 4093 0000ffc0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 4094 0000ffd0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 4095 0000ffe0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 4096 0000fff0 00 00 00 00 00 70 00 63 01 a1 6c 2b 00 07 3a b8 |.....p.c.?l+..:?|
我們可以看出,資料頁中儲存了一部分資料,算下來一共是768位元組,然後剩餘部分儲存在外部儲存頁中。那麼資料頁與外部儲存頁、外部儲存頁與外部儲存頁是如何連線在一起的呢?
我們觀察這一行:
3130 0000c390 61 61 00 00 00 02 00 00 00 04 00 00 00 26 00 00 |aa...........&..| 3131 0000c3a0 00 00 00 00 fc fc 00 00 00 00 00 00 00 00 00 00 |................|
這一行是字首768位元組的結尾。注意最後的20個位元組:
- 00 00 00 02:4位元組,代表外部儲存頁所在的space id
- 00 00 00 04:4位元組,代表第一個外部頁的Page no
- 00 00 00 26:4位元組,值為38,指向blob頁的header
- 00 00 00 00 00 00 fc fc:8位元組,代表該列存在外部儲存頁的總長度。此處的值為64764,加上字首768正好是65532。(注意一點,雖然表示BLOB長度的是8位元組,實際只有4個位元組能使用,所有對於BLOB欄位,儲存資料的最大長度為4GB。)
驗證下第一個外部儲存頁的頭部資訊:
4097 00010000 cd c3 b6 8e 00 00 00 04 00 00 00 00 00 00 00 00 |?ö.............| 4098 00010010 00 00 00 00 00 06 b8 a2 00 0a 00 00 00 00 00 00 |......??........| 4099 00010020 00 00 00 00 00 02 00 00 3f ca 00 00 00 05 61 61 |........??....aa| 4100 00010030 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| ... ...
前38個位元組為File Header(關於InnoDB資料頁的詳細結構請參見《MySQL技術內幕 InnoDB儲存引擎》4.4),這個簡單提一下:
- cd c3 b6 8e:4位元組,該頁的checksum。
- 00 00 00 04:4位元組,頁偏移,此頁為表空間中的第5個頁。
- 00 00 00 00:4位元組,當前頁的上一個頁。此頁為
<Uncompressed BLOB Page>
,所以沒有上一頁。 - 00 00 00 00:4位元組,當前頁的下一個頁。此頁為
<Uncompressed BLOB Page>
,所以沒有下一頁。 - 00 00 00 00 00 06 b8 a2:8位元組,該頁最後被修改的日誌序列位置LSN。
- 00 0a:2位元組,頁型別,0x000A代表BLOB頁。
- 00 00 00 00 00 00 00 00:8位元組,略過。
- 00 00 00 02:頁屬於哪個表空間,此處指表空間的ID為2。
之後是4位元組的00 00 3f ca
,這裡的值為16330,代表此BLOB頁的有效資料的位元組數。00 00 00 05
代表下一個BLOB頁的page number。
我們看最後一個<Uncompressed BLOB Page>
,第8個頁:
7169 0001c000 fa 78 9b 27 00 00 00 07 00 00 00 00 00 00 00 00 |?x.'............| 7170 0001c010 00 00 00 00 00 07 3a b8 00 0a 00 00 00 00 00 00 |......:?........| 7171 0001c020 00 00 00 00 00 02 00 00 3d 9e ff ff ff ff 61 61 |........=.????aa| 7172 0001c030 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| 7173 0001c040 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| ... ...
最後一頁的有效資料大小為0x00003d9e=15774,768+16330*3+15774 = 65532位元組,符合初始插入資料的大小。
由於這是最後一個<Uncompressed BLOB Page>
,所以指向下一個<Uncompressed BLOB Page>
的指標為ff ff ff ff。
由此我們可以很清晰的看出資料頁與BLOB頁的連線關係(引用淘寶資料庫月報上的一張圖):
我們來再看一個比較有意思的例子。:
CREATE TABLE `testblob` ( `blob1` blob NOT NULL, `blob2` blob NOT NULL, `blob3` blob NOT NULL, `blob4` blob NOT NULL, `blob5` blob NOT NULL, `blob6` blob NOT NULL, `blob7` blob NOT NULL, `blob8` blob NOT NULL, `blob9` blob NOT NULL, `blob10` blob NOT NULL, `blob11` blob NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; mysql> insert into testblob select repeat('a',1000),repeat('b',1000),repeat('c',1000),repeat('d',1000),repeat('e',1000),repeat('f',1000),repeat('g',1000),repeat('h',1000),repeat('i',1000),repeat('j',1000),repeat('k',1000); ERROR 1030 (HY000): Got error 139 from storage engine
我們建立一張新表,有11個blob欄位。然後向每個欄位插入1000位元組的資料,MySQL會提示ERROR 1030 (HY000): Got error 139 from storage engine
,什麼意思呢?
InnoDB是以B+樹來組織資料的,假如每一行資料都佔據一整個Page頁,那麼B+樹將退化為單連結串列,所以InnoDB規定了一個Page必須包含兩行資料。也就是一行資料儲存在Page上的大小大概為8000位元組。
而上面的例子,一行資料有11個1000位元組的資料,Page層肯定放不下,所以在Page層留下768*11=8448位元組,已經超過了8000位元組,所以MySQL會提示ERROR 1030 (HY000): Got error 139 from storage engine
。我們很輕鬆的定義一個欄位,來儲存11000個位元組,但是卻無法將他們分成11個欄位來儲存,有點意思!
那麼如何解決上面的問題呢?
- 將行格式轉為接下來要說的Dynamic格式。此種格式只用20位元組指向外部儲存空間。
- 將多個blob欄位轉為一個blob欄位。多個欄位可以用陣列儲存,然後json_encode打包進blob。
我們向表中插入一條有效記錄:
mysql> insert into testblob(blob1,blob2,blob3,blob4,blob5,blob6,blob7,blob8,blob9) select repeat('a',8000),repeat('b',8000),repeat('c',8000),repeat('d',8000),repeat('e',8000),repeat('f',8000),repeat('g',8000),repeat('h',8000),repeat('i',8000); Query OK, 1 row affected (0.12 sec) Records: 1 Duplicates: 0 Warnings: 0
[root@localhost mysql]# python py_innodb_page_info.py -v com/testblob.ibd page offset 00000000, page type <File Space Header> page offset 00000001, page type <Insert Buffer Bitmap> page offset 00000002, page type <File Segment inode> page offset 00000003, page type <B-tree Node>, page level <0000> page offset 00000004, page type <Uncompressed BLOB Page> page offset 00000005, page type <Uncompressed BLOB Page> page offset 00000006, page type <Uncompressed BLOB Page> page offset 00000007, page type <Uncompressed BLOB Page> page offset 00000008, page type <Uncompressed BLOB Page> page offset 00000009, page type <Uncompressed BLOB Page> page offset 0000000a, page type <Uncompressed BLOB Page> page offset 0000000b, page type <Uncompressed BLOB Page> page offset 0000000c, page type <Uncompressed BLOB Page> Total number of page: 13: Insert Buffer Bitmap: 1 Uncompressed BLOB Page: 9 File Space Header: 1 B-tree Node: 1 File Segment inode: 1
我們可以看出這一行資料有9個外部儲存頁,而我們一共就插入了9列資料,是不是當每一列的資料在page頁放不下,都單獨申請一個外部儲存頁,而互相之前不共享外部儲存頁。我們看一下page頁的結構就知道了:
3130 0000c390 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 61 |aaaaaaaaaaaaaaaa| 3131 0000c3a0 61 61 61 61 00 00 00 05 00 00 00 04 00 00 00 26 |aaaa...........&| ... ... 3180 0000c6b0 62 62 62 62 62 62 62 62 00 00 00 05 00 00 00 05 |bbbbbbbb........| 3181 0000c6c0 00 00 00 26 00 00 00 00 00 00 1c 40 63 63 63 63 |...&.......@cccc| ... ... 3229 0000c9c0 63 63 63 63 63 63 63 63 63 63 63 63 00 00 00 05 |cccccccccccc....| 3230 0000c9d0 00 00 00 06 00 00 00 26 00 00 00 00 00 00 1c 40 |.......&.......@| ... ...
根據前面的分析,我們現在可以看出,外部儲存頁是不共享的,即使一個列的資料多出一個位元組,這一個位元組也是獨佔一個16KB空間的大小,這很浪費儲存空間。(當然,這對現代計算機可能不是問題,呵呵)。
說了這麼多,總結下Compact格式儲存大資料的缺點:
- 由於存在768位元組的字首在Page頁,所以會存在能定義一個欄位,儲存11000位元組,但是不能定義11個欄位,每個欄位儲存1000位元組的”bug”。
- 外部儲存頁不共享,即使多餘一個位元組也是獨享16KB的頁面。
Dynamic行格式
接著我們首先看一下行格式為Dynamic是如何儲存大資料的:
mysql> select version(); +-----------+ | version() | +-----------+ | 5.7.14 | +-----------+ 1 row in set (0.00 sec) mysql> show table status like 'row'\G; *************************** 1. row *************************** Name: row Engine: InnoDB Version: 10 Row_format: Dynamic Rows: 0 Avg_row_length: 0 Data_length: 16384 Max_data_length: 0 Index_length: 0 Data_free: 0 Auto_increment: NULL Create_time: 2017-01-03 22:45:16 Update_time: NULL Check_time: NULL Collation: latin1_swedish_ci Checksum: NULL Create_options: Comment: 1 row in set (0.00 sec)
建立和compact格式一樣的表:
CREATE TABLE `row` ( `content` varchar(65532) NOT NULL DEFAULT '' ) ENGINE=InnoDB DEFAULT CHARSET=latin1 insert into row(content) select repeat('a',65532); Query OK, 1 row affected (0.03 sec) Records: 1 Duplicates: 0 Warnings: 0
看下頁分佈:
[root@localhost mysql]# python py_innodb_page_info.py -v row.ibd page offset 00000000, page type <File Space Header> page offset 00000001, page type <Insert Buffer Bitmap> page offset 00000002, page type <File Segment inode> page offset 00000003, page type <B-tree Node>, page level <0000> page offset 00000004, page type <Uncompressed BLOB Page> page offset 00000005, page type <Uncompressed BLOB Page> page offset 00000006, page type <Uncompressed BLOB Page> page offset 00000007, page type <Uncompressed BLOB Page> page offset 00000008, page type <Uncompressed BLOB Page> Total number of page: 9: Insert Buffer Bitmap: 1 Uncompressed BLOB Page: 5 File Space Header: 1 B-tree Node: 1 File Segment inode: 1
第4頁是資料頁,第5-9頁是二進位制頁。我們直接看磁碟中第4頁的資料:
3073 0000c000 dc 2d b0 f5 00 00 00 03 ff ff ff ff ff ff ff ff |.-..............| 3074 0000c010 00 00 00 00 00 a3 4b 59 45 bf 00 00 00 00 00 00 |......KYE.......| 3075 0000c020 00 00 00 00 00 36 00 02 00 a6 80 03 00 00 00 00 |.....6..........| 3076 0000c030 00 7f 00 05 00 00 00 01 00 00 00 00 00 00 00 00 |................| 3077 0000c040 00 00 00 00 00 00 00 00 00 64 00 00 00 36 00 00 |.........d...6..| 3078 0000c050 00 02 00 f2 00 00 00 36 00 00 00 02 00 32 01 00 |.......6.....2..| 3079 0000c060 02 00 1c 69 6e 66 69 6d 75 6d 00 02 00 0b 00 00 |...infimum......| 3080 0000c070 73 75 70 72 65 6d 75 6d 14 c0 00 00 10 ff f1 00 |supremum........| 3081 0000c080 00 00 00 02 00 00 00 00 00 07 07 a7 00 00 01 1b |................| 3082 0000c090 01 10 00 00 00 36 00 00 00 04 00 00 00 26 00 00 |.....6.......&..| 3083 0000c0a0 00 00 00 00 ff fc 00 00 00 00 00 00 00 00 00 00 |................| 3084 0000c0b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 3085 0000c0c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 3086 0000c0d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| 3087 0000c0e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................| ... ... ...
和Compact格式有著明顯的不同,當大資料在Page頁存放不下時,Dynamic行格式不會留768位元組在Page頁,並且將全部大資料都放在外部儲存頁。具體的資料頁和外部儲存頁的連線關係同Compact格式一樣。
我們再看看Dynamic格式的外部儲存頁是不是每一個列獨享外部儲存空間,還是同Compact格式實驗過程一樣:
CREATE TABLE `testblob` ( `blob1` blob NOT NULL, `blob2` blob NOT NULL, `blob3` blob NOT NULL, `blob4` blob NOT NULL, `blob5` blob NOT NULL, `blob6` blob NOT NULL, `blob7` blob NOT NULL, `blob8` blob NOT NULL, `blob9` blob NOT NULL, `blob10` blob NOT NULL, `blob11` blob NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1; mysql> insert into testblob(blob1,blob2,blob3,blob4,blob5,blob6,blob7,blob8,blob9,blob10,blob11) select repeat('a',8000),repeat('b',8000),repeat('c',8000),repeat('d',8000),repeat('e',8000),repeat('f',8000),repeat('g',8000),repeat('h',8000),repeat('i',8000),repeat('j',8000),repeat('k',8000); Query OK, 1 row affected (0.10 sec) Records: 1 Duplicates: 0 Warnings: 0
看一下外部儲存頁資料:
4599 00011f60 61 61 61 61 61 61 61 61 61 61 61 61 61 61 00 00 |aaaaaaaaaaaaaa..| 4600 00011f70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
好的,可以不用向下看其他列的了,Dynamic的外部儲存頁也不是共享的。
但是MySQL為什麼要這麼設計呢?可能是為了實現簡單吧,沿著連結串列通過有效資料大小就能讀取blob的全部資料。假如多個欄位的blob混在一起,可能設計更復雜,要更新每個欄位的偏移量之類的,更新的話頁資料管理也比較麻煩。我的個人猜測,呵呵。
總結下Dynamic格式儲存大資料的特點:
- 當資料頁放不下時,MySQL會將大資料全部放在外部儲存頁,資料頁只留指向外部儲存頁的指標。
- 外部儲存頁不共享,即使多餘一個位元組也是獨享16KB的頁面。
將列放入外部儲存頁的標準
當一行中的資料不能在資料頁中放下,需要申請外部儲存頁時,MySQL需要決定將哪一列的資料放到外部儲存頁,遵循的規則如下:
- 長度固定的欄位不會被放到外部儲存頁(int、char(N)等)
- 長度小於20位元組的欄位不會被放到外部儲存頁。(假如放到外部儲存頁,不僅會單獨佔據16KB,還要額外的20位元組指標,沒有必要)
- 對於Compact和REDUNDANT格式的行資料,長度小於768位元組的欄位不會被放到外部儲存頁。(這個原因很顯然,本來就不夠768位元組的字首,總不能生搬硬湊吧)。
當有多個大資料欄位滿足上面條件,需要被放到外部儲存頁時,MySQL會優先選擇大的欄位放到外部儲存頁,因為這樣可以最大限度的省下資料頁的空間,使得更多的欄位能夠被放到資料頁。
由於有較多的實驗過程,所以顯得比較亂,建議看到這篇文章人自己實踐一遍,畢竟自己動手會思考更多的問題與細節,理解的也比較深刻,哈哈哈。
參考資料:
http://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html
http://mysqlserverteam.com/externally-stored-fields-in-innodb/
https://www.percona.com/blog/2010/02/09/blob-storage-in-innodb/
http://mysql.taobao.org/monthly/2016/02/01/
相關文章
- mysql的text欄位長度MySql
- MySQL的欄位數量以及長度限制MySql
- SAP主資料的欄位長度(ECC6.0)
- MySQL中需要注意的欄位長度問題MySql
- oracle 修改表欄位的長度Oracle
- MySQL中修改一個資料庫下包含有某個相同欄位的所有表的欄位長度MySql資料庫
- mysql的varchar欄位最大長度真的是65535嗎?MySql
- sqlloader匯入資料_資料檔案的欄位超出最大長度SQL
- mysql變長型別欄位varchar值更新變長或變短底層檔案儲存原理MySql型別
- MySQL中欄位型別與合理的選擇欄位型別;int(11)最大長度是多少?varchar最大長度是多少?MySql型別
- 如何延長儲存伺服器上資料的儲存時間?伺服器
- oracle中number型欄位長度、精度及實際儲存狀態測試(zt)Oracle
- Oracle 修改欄位型別和長度Oracle型別
- SQL SERVER 查詢表的欄位名、資料型別和最大長度SQLServer資料型別
- 如何在EJB中獲得資料庫欄位的長度?(不是jdbc)請大家指點謝謝資料庫JDBC
- Mysql資料庫建立儲存過程實現往資料表中新增欄位的方法MySql資料庫儲存過程
- MySQL儲存過程-->長字串扯分MySql儲存過程字串
- 欄位長度前後端是否都需要做限制?後端
- 移動端長按儲存、取消長按儲存圖片
- 觸發器—一個表插入資料時其他欄位同步自增長欄位觸發器
- 不確定的資料結構試驗clob欄位儲存資料結構
- php讀取xml資料庫欄位超長處理PHPXML資料庫
- MySQL 5.6使用pt-online-schema-change線上修改大表欄位長度MySql
- mssql sqlserver 可以儲存二進位制資料的欄位型別詳解SQLServer型別
- DDL操作導致欄位長度變更修復方案
- MySQL - 一個欄位儲存多個ID時的查詢MySql
- MySQL VARCHAR型別欄位到底可以定義多長MySql型別
- [BUG反饋]username欄位的長度設定有點小問題。
- 如何查詢BAPI SD_SALESDOCUMENT_CHANGE裡欄位對應的資料庫儲存表API資料庫
- 【融雲分析】從過剩儲存資源到分散式時序資料庫的長儲存分散式資料庫
- 修改欄位長度應用會影響到生產效能
- 曹工改bug--本來以為很簡單的資料庫欄位長度不足的問題,最後竟然靠抓包才解決資料庫
- MySQL如何實現萬億級資料儲存?MySql
- 按位長度進行字串的分割輸出,長度不足補0字串
- 資料型別及長度資料型別
- TCP傳輸資料長度TCP
- [ 丹臣]INNODB與ORACLE單行儲存長度對比Oracle
- MySQL儲存毫秒資料的方法MySql