長沙優(yōu)化網站廠家百度在線客服系統(tǒng)
目錄
一 . 存儲:一個完整的數據存儲過程是怎樣的?
1.1 數據存儲過程
?1.1.1 創(chuàng)建MySQl 數據庫
1.1.1.1 為什么我們要先創(chuàng)建一個數據庫,而不是直接創(chuàng)建數據表?
1.1.1.2基本操作部分
1.2 選擇索引問題
二 . 字段:這么多的字段類型,應該如何定義
2.1 簡介
2.1.1 例子:
2.1.1.1解釋:
2.2 整數類型
2.2.1 如何選擇合適的整數類型
2.3 浮點數類型和定點類型
2.3.1 為什么浮點數類型的無符號只有有符號的一半取值范圍?
2.3.2 浮點數的精度問題
2.3.2.1 建表:
2.3.2.2 然后插入數據
2.3.2.3 查看表里面的數據
2.3.2.4?利用SQl語句進行價格相加:
2.3.2.4.1 sum:
2.3.2.4.1.1 導致這個的原因;
2.3.2.5 解決小數的精度問題?
2.4 文本類型
2.4 .1 詳細解釋TEXT類型
一 . 存儲:一個完整的數據存儲過程是怎樣的?
1.1 數據存儲過程
?MySQL是怎么進行數據存儲的。
存儲數據是處理數據的第一步,對各種繁雜的數據,進行有序和高效地存儲起來。
在MySQL中,完整的數據存儲過程共有4步,分別是 創(chuàng)建數據庫,確認字段,創(chuàng)建數據表,插入數據。
?1.1.1 創(chuàng)建MySQl 數據庫
數據存儲的第一步就是創(chuàng)建數據庫。
1.1.1.1 為什么我們要先創(chuàng)建一個數據庫,而不是直接創(chuàng)建數據表?
數據庫是MySQL里面最大的存儲單元,系統(tǒng)架構層次上看,MySQL數據庫系統(tǒng),從小到大依次是數據庫服務器,數據庫,數據表,數據表的行與列。
沒有數據庫,數據表就沒有載體,就無法存儲數據。
1.1.1.2基本操作部分
創(chuàng)建數據庫
create database demo;
刪除數據庫
drop database demo;
查看數據庫
show databases;
創(chuàng)建數據表:
create table demo.test
(
barcode text,
goodsname text,
price int
);
查看表結構
describe? demo.test;
查看所有表
show tables;
添加主鍵
alter table demo.test
add column itemnumber int primary key auto_increment
向表添加數據
insert into demo.test
(barcode,goodsname,price)
values('0001','本',3);
1.2 選擇索引問題
select count(*) from t; t中有id(主鍵),name,age,sex4個字段。假設數據10條,對sex添加索引。用explain 查看執(zhí)行計劃發(fā)現用了sex索引,為什么不是主鍵索引呢?主鍵索引應該更快的.
解答:
MySQL Innodb的主鍵索引是一個B+樹,數據存儲在葉子節(jié)點上,10條數據,就有10個葉子節(jié)點。
1. sex索引是輔助索引,也是一個B+樹,不同之處在于,葉子節(jié)點存儲的是主鍵值,由于sex只有2個
可能的值:男和女,因此,這個B+樹只有2個葉子節(jié)點,比主鍵索引的B+樹小的多
2. 這個表有主鍵,因此不存在所有字段都為空的記錄,所以COUNT(*)只要統(tǒng)計所有主鍵的值就可以
了,不需要回表讀取數據
3. SELECT COUNT(*) FROM t,使用sex索引,只需要訪問輔助索引的小B+樹,而使用主鍵索引,要
訪問主鍵索引的那個大B+樹,明細工作量大,這就是為什么,優(yōu)化器使用輔助索引的原因
二 . 字段:這么多的字段類型,應該如何定義
2.1 簡介
?MySQl中有很多字段類型,比如整數,文本,浮點數。
2.1.1 例子:
在銷售流水表中,需要定義商品銷售的數量。由于有稱重
商品,不能用整數,想當然地用了浮點數,為了確保精度,還用了 DOUBLE 類型。
結果卻造成了在沒有找零的情況下,客人無法結賬的重大錯誤,DOUBLE 類型是不精準的,不能使用。
2.1.1.1解釋:
浮點數在計算機中的內部表示是二進制的,而不是十進制的。對于某些常見的十進制小數(如0.1),其在二進制表示中是一個無限循環(huán)的小數。這樣就存在一些十進制小數無法準確轉換為浮點數的二進制表示。
當進行浮點數計算時,舍入誤差會逐漸累積。即使看似簡單的計算,例如0.1 + 0.1 + 0.1,也可能產生一個微小的舍入誤差。這意味著在處理貨幣或計量單位時,通過浮點數計算得到的結果可能與預期的結果有細微差異。
在結賬場景中,如果使用浮點數(DOUBLE)存儲商品銷售的數量和金額,并進行計算,那么可能會出現舍入誤差。例如,如果商品價格是0.1元,數量是3個,正確的總金額應該是0.3元。但由于浮點數的舍入誤差,實際計算時可能得到一個接近0.30000000000000004的結果。這樣就導致無法準確匹配預期的金額,客人無法正確結賬。
因此,在處理與貨幣或計量單位相關的數據時,浮點數(DOUBLE)類型不是一個理想的選擇,因為它可能引發(fā)舍入誤差和精度問題。更好的選擇是使用固定點數類型(如DECIMAL),它可以提供更高的精確度和準確性來處理這些情況,避免結賬錯誤的發(fā)生。
2.2 整數類型
整數類型一共5種:tinyint ,smallint,mediumint,int(integer),bigint。
2.2.1 如何選擇合適的整數類型
需要考慮存儲空間和可靠性的平衡問題:
1.占用字節(jié)數少的整數類型可以節(jié)省出存儲空間,如果太小了,可能會出現超出取值范圍的情況,引發(fā)系統(tǒng)問題。
例子:
在我們的項目中,商品編號采用的數據類型是 INT。
我們之所以沒有采用占用字節(jié)更少的 SMALLINT 類型整數,原因就在于,客戶門店中流通的
商品種類較多,而且,每天都有舊商品下架,新商品上架,這樣不斷迭代,日積月累。如果使
用 SMALLINT 類型,雖然占用字節(jié)數比 INT 類型的整數少,但是卻不能保證數據不會超出范
圍 65535。相反,使用 INT,就能確保有足夠大的取值范圍,不用擔心數據超出范圍影響可
靠性的問題。
注意:實際工作中,系統(tǒng)故障產生的成本遠遠超過增加幾個字段存儲空間所產生的成本,我們應該首先確保數據不會超過取值范圍,在這個前提下考慮如何節(jié)省存儲空間。
2.3 浮點數類型和定點類型
浮點數和定點數的特點是可以處理小數,將整數看成小數的特例。
浮點數類型:float,double,real?
float 表示單精度浮點數;4字節(jié)
double 表示 雙精度浮點數? ?8字節(jié)
real 默認 double,
如果要float:set sql_mode = " real_as_float";
2.3.1 為什么浮點數類型的無符號只有有符號的一半取值范圍?
原因是,MySQL 是按照這個格式存儲浮點數的:符號(S)、尾數(M)和階
碼(E)。因此,無論有沒有符號,MySQL 的浮點數都會存儲表示符號的部分。因此,所謂
的無符號數取值范圍,其實就是有符號數取值范圍大于等于零的部分。
2.3.2 浮點數的精度問題
2.3.2.1 建表:
CREATE TABLE demo.goodsmaster
(
barcode TEXT,
goodsname TEXT,
price DOUBLE,
itemnumber INT PRIMARY KEY AUTO_INCREMENT
);
2.3.2.2 然后插入數據
-- 第一條
INSERT INTO demo.goodsmaster
(
barcode,
goodsname,
price
)
VALUES
(
'0001',
'書',
0.47
);
-- 第二條
INSERT INTO demo.goodsmaster
(
barcode,
goodsname,
price
)
VALUES
(
'0002',
'筆',
0.44
);
-- 第三條
INSERT INTO demo.goodsmaster
(
barcode,
goodsname,
price
)
VALUES
(
'0002',
'膠水',
0.19
);
2.3.2.3 查看表里面的數據
SELECT * from demo.goodsmaster;
結果:
mysql> SELECT *
-> FROM demo.goodsmaster;
+---------+-----------+-------+------------+
| barcode | goodsname | price | itemnumber |
+---------+-----------+-------+------------+
| 0001 | 書 | 0.47 | 1 |
| 0002 | 筆 | 0.44 | 2 |
| 0002 | 膠水 | 0.19 | 3 |
+---------+-----------+-------+------------+
3 rows in set (0.00 sec)
2.3.2.4?利用SQl語句進行價格相加:
SELECT SUM(price)
FROM demo.goodsmaster;
2.3.2.4.1 sum:
關鍵字sum,MySQL的求和函數,MySQL聚合函數的一種,知道這個函數表述計算字段值的和就可以了。
我們應該理想的值,0.47+0.44+0.19 =1.1
結果:
mysql> SELECT SUM(price)
-> FROM demo.goodsmaster;
+--------------------+
| SUM(price) |查詢結果是 1.0999999999999999
?將類型改成float,輸出的值為1.0999999940395355,誤差更大。
當我們需要進行值對比作為條件進行查詢的時候,就會發(fā)生誤差。
比如:
SELECT *
FROM demo.goodsmaster
WHERE SUM(price)=1.1
2.3.2.4.1.1 導致這個的原因;
出在 MySQL 對浮點類型數據的存儲方式上。
MySQL 用 4 個字節(jié)存儲 FLOAT 類型數據,用 8 個字節(jié)來存儲 DOUBLE 類型數據。無論哪
個,都是采用二進制的方式來進行存儲的。比如 9.625,用二進制來表達,就是 1001.101,
?如果尾數不是 0 或 5(比如 9.624)。
在計算機中,所有數字都是以二進制的形式表示的。因此,將十進制小數轉換為二進制小數是非常重要的,這樣計算機才能夠進行準確的計算和精確的表示。證明這種轉換方式的正確性其實很簡單。我們知道,在十進制中,小數點左側的每一位數位的權重都是10的非負整數次冪,如:1000 100 10 1 . 1/10 1/100 1/1000
10^3 10^2 10^1 10^0 10^-1 10^-2 10^-3同樣地,在二進制中,小數點右側的每一位數位的權重都是2的負整數次冪,如:. 1/2 1/4 1/8 1/16 1/32 1/64
2^-1 2^-2 2^-3 2^-4 2^-5 2^-6 2^-7因此,我們可以將十進制小數乘以2,并取整數部分,再將所得到的小數部分繼續(xù)乘以2,直到小數部分為0或者達到所需要的位數。這樣,就可以通過二進制小數精確地表示十進制小數。當然,二進制小數并非適用于所有的十進制小數,有些十進制小數是無法精確地表示為有限的二進制小數的。但是,在實際應用中,我們通常只需要使用有限位數的二進制小數來進行計算。因此,通過乘以2并取整的方法來轉換小數可以滿足大多數應用場景的需求。
你就無法用一個二進制數來精確表達。怎么辦呢?就只好在取值允許的范圍內進行近似(四舍五入)?,F在你一定明白了,為什么數據類型是 DOUBLE 的時候,我們得到的結果誤差更小一些,而數據類型是 FLOAT 的時候,誤差會更大一下。原因就是,DOUBLE 有 8 位字節(jié),精度更高。
2.3.2.5 解決小數的精度問題?
定點數類型 decimal是一種用于精確表示小數的數據類型,它的實現方式可以保證精度的正確性。 decimal 類型一般由兩個部分組成:整數部分和小數部分。整數部分用于表示正負號和整數部分的數值,而小數部分用于表示小數的位數和數值。
在 decimal 類型中,精度是由小數部分的位數定義的。
例子:
decimal(5,2) 表示總共有 5 位數,其中 2 位是小數位。這意味著 decimal 類型可以表示從 -99.99 到 +99.99 的范圍內的任意小數,且小數部分會被精確地保留到兩位小數。
decimal類型的實現會使用一些算法來確保精度的正確性,例如四舍五入、進位等。這樣,無論使用 decimal 類型進行何種數學運算,系統(tǒng)都會在內部處理這些算法,以保證最終結果的精度是正確的。
因此,使用 decimal 類型可以有效地確保小數的精度是正確的。在進行計算過程中,如果需要保持較高的精度,請選擇合適的 decimal 類型和位數,以適應應用的需求。
2.4 文本類型
?對于存儲的條碼、商品名稱,都是字符串數據。這兩個字段的數據類型,我們可能都選擇了 TEXT 類型。
TEXT 類型是 MySQL 支持的文本類型的一種。此外,MySQL 還支持 CHAR、VARCHAR、
ENUM 和 SET 等文本類型。
CHAR(M):固定長度字符串。CHAR(M) 類型必須預先定義字符串長度。如果太短,數據
可能會超出范圍;如果太長,又浪費存儲空間。
VARCHAR(M): 可變長度字符串。VARCHAR(M) 也需要預先知道字符串的最大長度,不
過只要不超過這個最大長度,具體存儲的時候,是按照實際字符串長度存儲的。
TEXT:字符串。系統(tǒng)自動按照實際長度存儲,不需要預先定義長度。
ENUM: 枚舉類型,取值必須是預先設定的一組字符串值范圍之內的一個,必須要知道字
符串所有可能的取值。
SET:是一個字符串對象,取值必須是在預先設定的字符串值范圍之內的 0 個或多個,也必
須知道字符串所有可能的取值。
2.4 .1 詳細解釋TEXT類型
TEXT 類型也有 4 種,它們的區(qū)別就是最大長度不同。
TINYTEXT:255 字符(這里假設字符是 ASCII 碼,一個字符占用一個字節(jié),下同)。
TEXT: 65535 字符。
MEDIUMTEXT:16777215 字符。
LONGTEXT: 4294967295 字符(相當于 4GB)。
TEXT 有一個問題:由于實際存儲的長度不確定,
MySQL 不允許TEXT 類型的字段做主鍵。
遇到這種情況,我們只能采用 CHAR(M),或者 VARCHAR(M)。
?