一:MySQL數據類型
成都創新互聯公司主要從事網站設計制作、網站制作、網頁設計、企業做網站、公司建網站等業務。立足成都服務肅州,10余年網站建設經驗,價格優惠、服務專業,歡迎來電咨詢建站服務:18980820575
MySQL中定義數據字段的類型對你數據庫的優化是非常重要的
MySQL支持多種數據類型,大致可以分為三類:數值 日期/時間和字符串
二、數值類型
1.整數類型
2.浮點數
如果希望保證值比較準確,推薦使用定點數數據類型。MySql中的浮點類型有float,double和real。他們定義方式為:FLOAT(M,D) 、 REAL(M,D) 、 DOUBLE PRECISION(M,D)。
FLOAT和DOUBLE中的M和D的取值默認都為0,即除了最大最小值,不限制位數。允許的值理論上是-1.7976931348623157E+308~-2.2250738585072014E-308、0和2.2250738585072014E-308~1.7976931348623157E+308。M、D范圍如下:
(MySql5.7實測,與IEEE標準計算的實際是不同的,下面介紹):M取值范圍為0~255。FLOAT只保證6位有效數字的準確性,所以FLOAT(M,D)中,M=6時,數字通常是準確的。如果M和D都有明確定義,其超出范圍后的處理同decimal。
D取值范圍為0~30,同時必須=M。double只保證16位有效數字的準確性,所以DOUBLE(M,D)中,M=16時,數字通常是準確的。如果M和D都有明確定義,其超出范圍后的處理同decimal。
CHAR值時,在它們的右邊填充空格以達到指定的長度。當檢索到CHAR值時,尾部的空格被刪除掉,所以,我們在存儲時字符串右邊不能有空格,即使有,查詢出來后也會被刪除。在存儲或檢索過程中不進行大小寫轉換。
三、時間日期類型(5)
該“0”值如下:
請點擊輸入圖片描述
四、各種類型占用的存儲
1.數值類型
請點擊輸入圖片描述
定點數的比較特殊,而且與具體版本也有關系,此處單獨解釋:
使用二進制格式將9個十進制(基于10)數壓縮為4個字節來表示DECIMAL列值。每個值的整數和分數部分的存儲分別確定。每個9位數的倍數需要4個字節,并且“剩余的”位需要4個字節的一部分。下表給出了超出位數的存儲需求:
請點擊輸入圖片描述
2.時間日期
請點擊輸入圖片描述
從版本5.6.4開始,存儲需求就有所改變,根據精度而定。不確定部分需要的存儲如下:
請點擊輸入圖片描述
比如,TIME(0), TIME(2), TIME(4), 和TIME(6) 分別使用3, 4, 5, 6 bytes。
3.字符串
請點擊輸入圖片描述
4.類型的選擇
為了優化存儲,在任何情況下均應使用最精確的類型。
例如,如果列的值的范圍為從1到99999,若使用整數,則MEDIUMINT UNSIGNED是好的類型。在所有可以表示該列值的類型中,該類型使用的存儲最少。
用精度為65位十進制數(基于10)對DECIMAL 列進行所有基本計算(+、-、*、/)。
使用雙精度操作對DECIMAL值進行計算。如果準確度不是太重要或如果速度為最高優先級,DOUBLE類型即足夠了。為了達到高精度,可以轉換到保存在BIGINT中的定點類型。這樣可以用64位整數進行所有計算,根據需要將結果轉換回浮點值。
5.使用其他數據庫的SQL語句
為了使用為其它數據庫編寫的SQL執行代碼,MySQL按照下表所示對列類型進行映射。通過這些映射,可以很容易地從其它數據庫引擎將表定義導入到MySQL中:
請點擊輸入圖片描述
背景
MySQL 一直以來都有 TEXT、BLOB 等類型用來存儲圖片、視頻等大對象信息。比如一張圖片,隨便一張都 5M 以上。視頻也是,隨便一部視頻就是 2G 以上。
假設用 MySQL 來存放電影視頻等信息,一部是 2G,那么存儲 1000 部就是 2TB,2TB 也就是 1000 條記錄而已,但是對數據庫性能來說,不僅僅是看記錄數量,更主要的還得看占用磁盤空間大小。空間大了,所有以前的經驗啥的都失效了。
所以一般來說存放這類信息,也就是存儲他們的存放路徑,至于文件本身存放在哪里,那這就不是數據庫考慮的范疇了。數據庫只關心怎么來的快,怎么來的小。
舉例
雖然不推薦 MySQL 這樣做,但是也得知道 MySQL 該怎么做才行,做到心里有數。比如下面一張微信圖片,大概 5M 的樣子。
root@ytt:/var/lib/mysql-files# ls -sihl 微信圖片_20190711095019.jpg274501 5.4M -rw-r--r-- 1 root root 5.4M Jul 11 07:17 微信圖片_20190711095019.jpg
拷貝 100 份這樣的圖片來測試
root@ytt:/var/lib/mysql-files# for i in `seq 1 100`; do cp 微信圖片_20190711095019.jpg "$i".jpg;done;
root@ytt:/var/lib/mysql-files# ls
100.jpg ? 17.jpg ?25.jpg ?33.jpg ?41.jpg ?4.jpg ? 58.jpg ?66.jpg ?74.jpg ?82.jpg ?90.jpg ?99.jpg ?f8.tsv
10.jpg ? ?18.jpg ?26.jpg ?34.jpg ?42.jpg ?50.jpg ?59.jpg ?67.jpg ?75.jpg ?83.jpg ?91.jpg ?9.jpg ? 微信圖片_20190711095019.jpg
1111.jpg ?19.jpg ?27.jpg ?35.jpg ?43.jpg ?51.jpg ?5.jpg ? 68.jpg ?76.jpg ?84.jpg ?92.jpg ?f1.tsv
11.jpg ? ?1.jpg ? 28.jpg ?36.jpg ?44.jpg ?52.jpg ?60.jpg ?69.jpg ?77.jpg ?85.jpg ?93.jpg ?f2.tsv
12.jpg ? ?20.jpg ?29.jpg ?37.jpg ?45.jpg ?53.jpg ?61.jpg ?6.jpg ? 78.jpg ?86.jpg ?94.jpg ?f3.tsv
13.jpg ? ?21.jpg ?2.jpg ? 38.jpg ?46.jpg ?54.jpg ?62.jpg ?70.jpg ?79.jpg ?87.jpg ?95.jpg ?f4.tsv
14.jpg ? ?22.jpg ?30.jpg ?39.jpg ?47.jpg ?55.jpg ?63.jpg ?71.jpg ?7.jpg ? 88.jpg ?96.jpg ?f5.tsv
15.jpg ? ?23.jpg ?31.jpg ?3.jpg ? 48.jpg ?56.jpg ?64.jpg ?72.jpg ?80.jpg ?89.jpg ?97.jpg ?f6.tsv
16.jpg ? ?24.jpg ?32.jpg ?40.jpg ?49.jpg ?57.jpg ?65.jpg ?73.jpg ?81.jpg ?8.jpg ? 98.jpg ?f7.tsv
我們建三張表,分別用 LONGBLOB、LONGTEXT 和 VARCHAR 來存儲這些圖片信息
mysql show create table tt_image1G
*************************** 1. row ***************************
Table: tt_image1
Create Table: CREATE TABLE `tt_image1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`image_file` longblob,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql show create table tt_image2G
*************************** 1. row ***************************
Table: tt_image2
Create Table: CREATE TABLE `tt_image2` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`image_file` longtext,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
mysql show create table tt_image3G
*************************** 1. row ***************************
Table: tt_image3
Create Table: CREATE TABLE `tt_image3` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`image_file` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
1 row in set (0.00 sec)
我們來給三張表插入 100 張圖片(插入前,建議把 max_allowed_packet 設置到最大)
tt_image1
root@ytt:/var/lib/mysql-files# for i in `seq 1 100`;
do mysql -S /var/run/mysqld/mysqld.sock -e "insert into ytt.tt_image1(image_file)
values (load_file('/var/lib/mysql-files/$i.jpg'))";done;
tt_image2
root@ytt:/var/lib/mysql-files# for i in `seq 1 100`;
do mysql -S /var/run/mysqld/mysqld.sock -e "insert into ytt.tt_image2(image_file)
values (hex(load_file('/var/lib/mysql-files/$i.jpg')))";done;
tt_image3
root@ytt:/var/lib/mysql-files# aa='begin;';for i in `seq 1 100`;
do aa=$aa"insert into ytt.tt_image3(image_file) values
('/var/lib/mysql-files/$i.jpg');";
done;aa=$aa'commit;';mysql -S /var/run/mysqld/mysqld.sock -e "`echo $aa`";
檢查下三張表記錄數
mysql select 'tt_image1' as name ,count(*) from tt_image1 union allselect 'tt_image2',count(*) from tt_image2 union all select 'tt_image3', count(*) from tt_image3;+-----------+----------+| name ? ? ?| count(*) |+-----------+----------+| tt_image1 | ? ? ?100 || tt_image2 | ? ? ?100 || tt_image3 | ? ? ?100 |+-----------+----------+3 rows in set (0.00 sec)
看下文件大小,可以看到實際大小排名,LONGTEXT 字段存儲的最大,LONGBLOB 字段縮小到一半,最小的是存儲圖片路徑的表 tt_image3。所以這里從存儲空間來看,存放路徑最占優勢。
root@ytt:/var/lib/mysql/ytt# ls -silhS tt_image*274603 1.1G -rw-r----- 1 mysql mysql 1.1G Jul 11 07:27 tt_image2.ibd274602 545M -rw-r----- 1 mysql mysql 544M Jul 11 07:26 tt_image1.ibd274605 ?80K -rw-r----- 1 mysql mysql 112K Jul 11 07:27 tt_image3.ibd
那么怎么把圖片取出來呢?
tt_image3 肯定是最容易的
mysql select * from tt_image3;+----+----------------------------+| id | image_file ? ? ? ? ? ? ? ? |+----+----------------------------+| ?1 | /var/lib/mysql-files/1.jpg |+----+----------------------------+...100 rows in set (0.00 sec)
tt_image1 直接導出來二進制文件即可,下面我寫了個存儲過程,導出所有圖片。
mysql DELIMITER $$mysql USE `ytt`$$mysql DROP PROCEDURE IF EXISTS `sp_get_image`$$mysql CREATE DEFINER=`ytt`@`localhost` PROCEDURE `sp_get_image`()mysql BEGIN ? ? ?DECLARE i,cnt INT DEFAULT 0; ? ? ?SELECT COUNT(*) FROM tt_image1 WHERE 1 INTO cnt; ? ? ?WHILE i cnt DO ? ? ? ?SET @stmt = CONCAT('select image_file from tt_image1 ?limit ',i,',1 into dumpfile ''/var/lib/mysql-files/image',i,'.jpg'''); ? ? ? ?PREPARE s1 FROM @stmt; ? ? ? ?EXECUTE s1; ? ? ? ?DROP PREPARE s1; ? ? ?SET i = i + 1; ? ? ?END WHILE; ? ? ?END$$mysql DELIMITER ;mysql call sp_get_image;
tt_image2 類似,把 select 語句里 image_file 變為 unhex(image_file) 即可。
總結
這里我舉了個用 MySQL 來存放圖片的例子,總的來說有以下三點:
占用磁盤空間大(這樣會帶來各種各樣的功能與性能問題,比如備份,寫入,讀取操作等)
使用不易
還是推薦用文件路徑來代替實際的文件內容存放
實數是帶有小數部分的數字。然而,它們不只是為了存儲小數部分,也可以使用
DEClMAL 存儲比 BIGINT還大的整數。 MySQL 既支持精確類型,也支持不精確類型。
FLOAT 和 DOUBLE 類型支持使用標準的渾點運算進行近似計算。如果需要知道浮點運算是
怎么計算的,則需要研究所使用的平臺的浮點數的具體實現。
DECIMAL 類型用于存儲精確的小數。在 MySQL 5.0 和更高版本, DECIMAL 類型支持精確 計算。 MySQL 4.1 以及更早版本則使用浮點運算來實現 DECIAML 的計算,這樣做會因為 精度損失導致一些奇怪的結果。在這些版本的 MySQL 中,DEClMAL 只是一個"存儲類型"。
因為 CPU 不支持對 DEClMAL 的直接計算,所以在 MySQL 5.0 以及更高版本中, MySQL 服務器自身實現了 DECIMAL 的高精度計算。相對而言, CPU 直接支持原生浮點計算,所 以浮點運算明顯更快。
浮點和 DECIMAL 類型都可以指定精度。對于 DECIMAL 列,可以指定小數點前后所允許的 最大位數。這會影響列的空間消耗。 MySQL 5.0 和更高版本將數字打包保存到一個二進 制字符串中(每 4個字節存 9個數字)。例如, DEClMAL(18 ,9)小數點兩邊將各存儲 9個 數字,一共使用 9 個字節:小數點前的數字用 4 個字節,小數點后的數字用 4 個字節, 小數點本身占 1個字節。
MySQL 5.0 和更高版本中的 DEClMAL 類型允許最多 65個數字。而早期的 MySQL 版本中 這個限制是254個數字,并且保存為未壓縮的字符串(每個數字一個字節)。然而,這些(早 期)版本實際上并不能在計算中使用這么大的數字,因為 DECIMAL 只是一種存儲格式: 在計算中 DEClMAL 會轉換為 DOUBLE 類型。
有多種方法可以指定浮點列所需要的精度,這會使得 MySQL 悄悄選擇不同的數據類型, 或者在存儲時對值進行取舍。這些精度定義是非標準的,所以我們建議只指定數據類型, 不指定精度。
浮點類型在存儲同樣范圍的值時,通常比 DECIMAL 使用更少的空間。 FLOAT 使用 4個字 節存儲。 DOUBLE 占用8個字節,相比 FLOAT有更高的精度和更大的范圍。和整數類型一樣, 能選擇的只是存儲類型 IMySQL 使用 DOUBLE 作為內部浮點計算的類型。
因為需要額外的空間和計算開銷,所以應該盡量只在對小數進行精確計算時才使用
DECIMAL一一例如存儲財務數據。但在數據量比較大的時候,可以考慮使用 BIGINT 代替
DECIMAL,將需要存儲的貨幣單位根據小數的位數乘以相應的倍數即可。假設要存儲財
務數據精確到萬分之一分,則可以把所有金額乘以一百萬,然后將結果存儲在 BIGI町里,
這樣可以同時避免浮點存儲計算不精確和 DECIMAL 精確計算代價高的問題。
本文名稱:mysql怎么存高精度 mysql怎么存儲大字段
標題網址:http://vcdvsql.cn/article2/doishoc.html
成都網站建設公司_創新互聯,為您提供軟件開發、標簽優化、網站設計公司、自適應網站、網站制作、網站策劃
聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯