数据库之存储引擎,数据类型-30
生活随笔
收集整理的這篇文章主要介紹了
数据库之存储引擎,数据类型-30
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
數(shù)據(jù)庫(kù)之存儲(chǔ)引擎,數(shù)據(jù)類型-30 數(shù)據(jù)存儲(chǔ)引擎 什么是引擎 ? 一個(gè)功能的核心部分? ? ? ? 引擎可以被分類 為什么要分類? 自然 增壓的 汽油 柴油 電動(dòng) 混合動(dòng)力 天然氣 核動(dòng)力 燒水 汽油 動(dòng)力弱一點(diǎn) 噪音小 震動(dòng)小 柴油 動(dòng)力強(qiáng) 污染大 噪音大 振動(dòng)大 需求場(chǎng)景的不同催生了不同的引擎類別 回到mysql 核心功能是存儲(chǔ)數(shù)據(jù) 涉及到存儲(chǔ)數(shù)據(jù)的代碼 就稱之為存儲(chǔ)引擎 根據(jù)不同的需求 也有著不同的引擎分類 egon博客上寫的如下解釋: 存儲(chǔ)引擎說白了就是如何存儲(chǔ)數(shù)據(jù)、如何為存儲(chǔ)的數(shù)據(jù)建立索引和如何更新、查詢數(shù)據(jù)等技術(shù)的實(shí)現(xiàn)方 法。因?yàn)樵陉P(guān)系數(shù)據(jù)庫(kù)中數(shù)據(jù)的存儲(chǔ)是以表的形式存儲(chǔ)的,所以存儲(chǔ)引擎也可以稱為表類型(即存儲(chǔ)和 操作此表的類型) 在Oracle 和SQL Server等數(shù)據(jù)庫(kù)中只有一種存儲(chǔ)引擎,所有數(shù)據(jù)存儲(chǔ)管理機(jī)制都是一樣的。而MySql 數(shù)據(jù)庫(kù)提供了多種存儲(chǔ)引擎。用戶可以根據(jù)不同的需求為數(shù)據(jù)表選擇不同的存儲(chǔ)引擎,用戶也可以根據(jù) 自己的需要編寫自己的存儲(chǔ)引擎 命令:show engines;可以查看所有的數(shù)據(jù)庫(kù)引擎。 =========================================================== 關(guān)于引擎的介紹: #InnoDB 存儲(chǔ)引擎支持事務(wù),其設(shè)計(jì)目標(biāo)主要面向聯(lián)機(jī)事務(wù)處理(OLTP)的應(yīng)用。其 特點(diǎn)是行鎖設(shè)計(jì)、支持外鍵,并支持類似 Oracle 的非鎖定讀,即默認(rèn)讀取操作不會(huì)產(chǎn)生鎖。?從 MySQL 5.5.8 版本開始是默認(rèn)的存儲(chǔ)引擎。 InnoDB 存儲(chǔ)引擎將數(shù)據(jù)放在一個(gè)邏輯的表空間中,這個(gè)表空間就像黑盒一樣由 InnoDB 存儲(chǔ)引擎自身來管理。從 MySQL 4.1(包括 4.1)版本開始,可以將每個(gè) InnoDB 存儲(chǔ)引擎的 表單獨(dú)存放到一個(gè)獨(dú)立的 ibd 文件中。此外,InnoDB 存儲(chǔ)引擎支持將裸設(shè)備(row disk)用 于建立其表空間。 InnoDB 通過使用多版本并發(fā)控制(MVCC)來獲得高并發(fā)性,并且實(shí)現(xiàn)了 SQL 標(biāo)準(zhǔn) 的 4 種隔離級(jí)別,默認(rèn)為 REPEATABLE 級(jí)別,同時(shí)使用一種稱為 netx-key locking 的策略來 避免幻讀(phantom)現(xiàn)象的產(chǎn)生。除此之外,InnoDB 存儲(chǔ)引擎還提供了插入緩沖(insert buffer)、二次寫(double write)、自適應(yīng)哈希索引(adaptive hash index)、預(yù)讀(read ahead) 等高性能和高可用的功能。 對(duì)于表中數(shù)據(jù)的存儲(chǔ),InnoDB 存儲(chǔ)引擎采用了聚集(clustered)的方式,每張表都是按 主鍵的順序進(jìn)行存儲(chǔ)的,如果沒有顯式地在表定義時(shí)指定主鍵,InnoDB 存儲(chǔ)引擎會(huì)為每一 行生成一個(gè) 6 字節(jié)的 ROWID,并以此作為主鍵。?InnoDB 存儲(chǔ)引擎是 MySQL 數(shù)據(jù)庫(kù)最為常用的一種引擎,Facebook、Google、Yahoo 等 公司的成功應(yīng)用已經(jīng)證明了 InnoDB 存儲(chǔ)引擎具備高可用性、高性能以及高可擴(kuò)展性。對(duì)其 底層實(shí)現(xiàn)的掌握和理解也需要時(shí)間和技術(shù)的積累。如果想深入了解 InnoDB 存儲(chǔ)引擎的工作 原理、實(shí)現(xiàn)和應(yīng)用,可以參考《MySQL 技術(shù)內(nèi)幕:InnoDB 存儲(chǔ)引擎》一書。 #MyISAM 存儲(chǔ)引擎不支持事務(wù)、表鎖設(shè)計(jì)、支持全文索引,主要面向一些 OLAP 數(shù) 據(jù)庫(kù)應(yīng)用,在 MySQL 5.5.8 版本之前是默認(rèn)的存儲(chǔ)引擎(除 Windows 版本外)。數(shù)據(jù)庫(kù)系統(tǒng) 與文件系統(tǒng)一個(gè)很大的不同在于對(duì)事務(wù)的支持,MyISAM 存儲(chǔ)引擎是不支持事務(wù)的。究其根本,這也并不難理解。用戶在所有的應(yīng)用中是否都需要事務(wù)呢?在數(shù)據(jù)倉(cāng)庫(kù)中,如果沒有 ETL 這些操作,只是簡(jiǎn)單地通過報(bào)表查詢還需要事務(wù)的支持嗎?此外,MyISAM 存儲(chǔ)引擎的另一個(gè)與眾不同的地方是,它的緩沖池只緩存(cache)索引文件,而不緩存數(shù)據(jù)文件,這與 大多數(shù)的數(shù)據(jù)庫(kù)都不相同。#NDB 存儲(chǔ)引擎?2003 年,MySQL AB 公司從 Sony Ericsson 公司收購(gòu)了 NDB 存儲(chǔ)引擎。?NDB 存儲(chǔ)引擎是一個(gè)集群存儲(chǔ)引擎,類似于 Oracle 的 RAC 集群,不過與 Oracle RAC 的 share everything 結(jié)構(gòu)不同的是,其結(jié)構(gòu)是 share nothing 的集群架構(gòu),因此能提供更高級(jí)別的 高可用性。NDB 存儲(chǔ)引擎的特點(diǎn)是數(shù)據(jù)全部放在內(nèi)存中(從 5.1 版本開始,可以將非索引數(shù) 據(jù)放在磁盤上),因此主鍵查找(primary key lookups)的速度極快,并且能夠在線添加 NDB 數(shù)據(jù)存儲(chǔ)節(jié)點(diǎn)(data node)以便線性地提高數(shù)據(jù)庫(kù)性能。由此可見,NDB 存儲(chǔ)引擎是高可用、 高性能、高可擴(kuò)展性的數(shù)據(jù)庫(kù)集群系統(tǒng),其面向的也是 OLTP 的數(shù)據(jù)庫(kù)應(yīng)用類型。 #Memory 存儲(chǔ)引擎正如其名,Memory 存儲(chǔ)引擎中的數(shù)據(jù)都存放在內(nèi)存中,數(shù)據(jù)庫(kù)重啟或發(fā)生崩潰,表中的數(shù)據(jù)都將消失。它非常適合于存儲(chǔ) OLTP 數(shù)據(jù)庫(kù)應(yīng)用中臨時(shí)數(shù)據(jù)的臨時(shí)表,也可以作為 OLAP 數(shù)據(jù)庫(kù)應(yīng)用中數(shù)據(jù)倉(cāng)庫(kù)的維度表。Memory 存儲(chǔ)引擎默認(rèn)使用哈希 索引,而不是通常熟悉的 B+ 樹索引。 #Infobright 存儲(chǔ)引擎?第三方的存儲(chǔ)引擎。其特點(diǎn)是存儲(chǔ)是按照列而非行的,因此非常 適合 OLAP 的數(shù)據(jù)庫(kù)應(yīng)用。其官方網(wǎng)站是 http://www.infobright.org/,上面有不少成功的數(shù)據(jù) 倉(cāng)庫(kù)案例可供分析。 #NTSE 存儲(chǔ)引擎網(wǎng)易公司開發(fā)的面向其內(nèi)部使用的存儲(chǔ)引擎。目前的版本不支持事務(wù), 但提供壓縮、行級(jí)緩存等特性,不久的將來會(huì)實(shí)現(xiàn)面向內(nèi)存的事務(wù)支持。 #BLACKHOLE黑洞存儲(chǔ)引擎,可以應(yīng)用于主備復(fù)制中的分發(fā)主庫(kù)。 MySQL 數(shù)據(jù)庫(kù)還有很多其他存儲(chǔ)引擎,上述只是列舉了最為常用的一些引擎。如果 你喜歡,完全可以編寫專屬于自己的引擎,這就是開源賦予我們的能力,也是開源的魅力所在。 =========================================================== 可以看到,在配置文件里已經(jīng)指定了默認(rèn)的存儲(chǔ)引擎。 不同的引擎測(cè)試: 創(chuàng)建表時(shí)在最后指定引擎名稱 engine = xxx create table t1(id int)engine=innodb create table t1(id int not null)engine=csv create table t1(id int)engine=memory create table t1(id int)engine=blackhole insert into t1 value(1); insert into t2 value(1); insert into t3 value(1); insert into t4 value(1); 總結(jié): innodb是默認(rèn)的引擎 因?yàn)?它是永久存儲(chǔ) 并且 支持事務(wù),行鎖,外鍵 非鎖定讀(默認(rèn)讀取操作不會(huì)產(chǎn)生鎖) 創(chuàng)建表的完整語法 create table 表名( 字段名1 類型[(寬度) 約束條件], 字段名2 類型[(寬度) 約束條件], 字段名3 類型[(寬度) 約束條件] ); 注意注意注意:表中的最后一個(gè)字段不要加逗號(hào)? #注意:1. 在同一張表中,字段名是不能相同 ? ? ? ? ? ? ? 2. 寬度和約束條件可選 ? ? ? ? ? ? ? 3. 字段名和類型是必須的 長(zhǎng)度用于設(shè)置數(shù)據(jù)的長(zhǎng)度 數(shù)據(jù)類型也是一種約束 約束指的是除了數(shù)據(jù)類型外的額外的規(guī)范 如果添加的數(shù)據(jù)超過了指定的長(zhǎng)度范圍,超出范圍的就丟棄; 注意: 字段名 和 表名 庫(kù)名 都不能是mysql的關(guān)鍵字 比如select from not..... ***** 例子: mysql> create database db1 charset utf8; mysq> use db1;? mysq> create table t1( ? ? ? ? -> id int, ? ? ? ? -> name varchar(50), ? ? ? ? -> sex enum('male','female'), ? ? ? ? -> age int(3) -> ); ?mysq> show tables;?#查看db1庫(kù)下所有表名 命令(desc 表名;)|| (show columns from 表名;):獲取表結(jié)構(gòu) desc是describe的縮寫 mysq> select id,name,sex,age?from?t1; ? ? ? ? ? ? ?Empty set (0.00 sec) 往表里只插入一列id數(shù)據(jù):
數(shù)據(jù)類型之整數(shù)型 數(shù)據(jù)類型 為什么需要將數(shù)據(jù)分類? 1.為了描述事物 更加準(zhǔn)確 2.描述起來更方便 3.節(jié)省內(nèi)存空間 1 a 你 utf8 下 5個(gè)字節(jié) 1 a b c unicode 6個(gè)字節(jié) mysql支持的數(shù)據(jù)類型: 整型 ***? ? ? ? ?***? ? ? ? ? ? ?***? ? ? ? ? *****? ? ?*** tinyint smallint mediumint? ? ?int? ?bigint 字節(jié)數(shù): 1? ? ? ?2? ? ? ? ? ? ? 3? ? ? ? ? ? ? ? 4? ? ? ?8 默認(rèn)情況下整型是有符號(hào)的 需要用一個(gè)二進(jìn)制位存儲(chǔ)符號(hào) 給整型加上 約束 unsigned來表示無符號(hào) 如果數(shù)據(jù)超出范圍就盡可能保存最大的 例如 在無符號(hào)下 保存256 其實(shí)存的255 如果有符號(hào) 例如 tinyint 保存-1280 其實(shí)存的是-128 是最小值 ======================================== tinyint[(m)] [unsigned] [zerofill] m為顯示的長(zhǎng)度,不寫默認(rèn)為3。 小整數(shù)(一個(gè)字節(jié),也就是8個(gè)比特位),數(shù)據(jù)類型用于保存一些范圍的整數(shù) 數(shù)值范圍: 有符號(hào): -128 ~ 127 無符號(hào): 0 ~ 255 PS: MySQL中無布爾值,使用tinyint(1)構(gòu)造。 ======================================== int[(m)][unsigned][zerofill] m為顯示的長(zhǎng)度,不寫默認(rèn)為10。 整數(shù)(4個(gè)字節(jié),也就是32個(gè)比特位),數(shù)據(jù)類型用于保存一些范圍的整數(shù) 數(shù)值范圍: 有符號(hào): -2147483648 ~?2147483647 無符號(hào): 0 ~ 4294967295(2 ** 32 -1) ======================================== bigint[(m)][unsigned][zerofill] 大整數(shù),數(shù)據(jù)類型用于保存一些范圍的整數(shù) 數(shù)值范圍: 有符號(hào): -9223372036854775808 ~ 9223372036854775807 無符號(hào): 0 ~ 18446744073709551615 修改嚴(yán)格模式: 以上特性的出現(xiàn)是因?yàn)?mysql處于非嚴(yán)格模式 查看當(dāng)前模式 show variables like "sql_mode"; 修改為嚴(yán)格模式 set global sql_mode = "STRICT_TRANS_TABLES"; 嚴(yán)格模式下 如果值超出范圍就直接報(bào)錯(cuò),在一些版本中默認(rèn)就是嚴(yán)格模式! 在我們的正常開發(fā)中,我們應(yīng)該先判斷數(shù)據(jù)的正確性,沒有問題在發(fā)給數(shù)據(jù)庫(kù) 怎么選擇: 得根據(jù)實(shí)際情況來判斷,能夠保存你的數(shù)據(jù)的最小類型 長(zhǎng)度限制對(duì)于整型的意義: create table t10(id int(1)); insert into t10 value(454555); select *from t10; 發(fā)現(xiàn)這個(gè)數(shù)也存儲(chǔ)成功 說明 這里長(zhǎng)度指的不是存儲(chǔ)容量限制 而是顯示的寬度 如果你的數(shù)據(jù)超過了顯示寬度 有幾個(gè)顯示幾個(gè) 如果不足 則補(bǔ)全到指定長(zhǎng)度 得告訴它用什么來補(bǔ)全 create table t13(id int(10) zerofill);(zerofill用零補(bǔ)) 總結(jié) : 這個(gè)10,不是容量限制 而是 顯示寬度 要限制顯示寬度 1.創(chuàng)建表時(shí) 給整型加上寬度 2.加上zerofill約束
數(shù)據(jù)類型之浮點(diǎn)型 浮點(diǎn)型: 小數(shù)型 分類: float ***** double **** decimal ***** 字節(jié)數(shù): 4 8 不確定(手動(dòng)指定) 給浮點(diǎn)設(shè)置寬度限制 float(m,d) #m的最大值為255,d的最大值為30,精度最小 double(m,d) #m的最大值為255,d的最大值為30,精度中等 decimal(m,d) #m的最大值為65,d的最大值為30,精度最高 長(zhǎng)度說明 ***** m表示 這個(gè)浮點(diǎn)數(shù)整體的長(zhǎng)度 d表示 小數(shù)部分的長(zhǎng)度 例如: float(5,3) 最大值: 99.999 區(qū)別 ***** 相同點(diǎn): 小數(shù)部分最大長(zhǎng)度都是30 float和double的最大長(zhǎng)度為255 不同點(diǎn): decimal的整體最大長(zhǎng)度65 精度不同 double 比 float 精度高 decimal 是準(zhǔn)確的 不會(huì)丟失精度 如何選擇:你對(duì)精確度要求高你就使用 decimal 例子: 可以看到float的精度幾乎只有double的一半,decimal的精度最高,一點(diǎn)都沒有出錯(cuò)。
數(shù)據(jù)類型之時(shí)間類型 分類 time 時(shí)分秒 HH:MM:SS *** year 年份 *** date 日期 年月日 *** datetime 日期加時(shí)間 年月日 時(shí)分秒 年份最大是9999 ***** timestamp 時(shí)間戳 從1970-1-1開始算 年份最大是2037 ***** TIME HH:MM:SS('-838:59:59'/'838:59:59') YEAR YYYY(1901/2155) DATE YYYY-MM-DD(1000-01-01/9999-12-31) DATETIME YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 ) TIMESTAMP YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某時(shí)) 共同點(diǎn): 時(shí)間的存取通過字符串類型 都可以使用now()函數(shù)來插入當(dāng)前時(shí)間 datetime不寫now()方法時(shí),默認(rèn)插入為空 datetime 和 時(shí)間戳都能夠表示日期和時(shí)間 不同之處是: 年份最大范圍不同 時(shí)間戳可以為空 代表當(dāng)前時(shí)間,如圖: 時(shí)間戳在你更新記錄時(shí) 會(huì)自動(dòng)更新為當(dāng)前時(shí)間,如圖: 在實(shí)際應(yīng)用的很多場(chǎng)景中,MySQL的這兩種日期類型都能夠滿足我們的需要,存儲(chǔ)精度都為秒,但在某些情況下,會(huì)展現(xiàn)出他們各自的優(yōu)劣。下面就來總結(jié)一下兩種日期類型的區(qū)別。 1.DATETIME的日期范圍是1001——9999年,TIMESTAMP的時(shí)間范圍是1970——2038年。 2.DATETIME存儲(chǔ)時(shí)間與時(shí)區(qū)無關(guān),TIMESTAMP存儲(chǔ)時(shí)間與時(shí)區(qū)有關(guān),顯示的值也依賴于時(shí)區(qū)。在mysql服務(wù)器,操作系統(tǒng)以及客戶端連接都有時(shí)區(qū)的設(shè)置。 3.DATETIME使用8字節(jié)的存儲(chǔ)空間,TIMESTAMP的存儲(chǔ)空間為4字節(jié)。因此,TIMESTAMP比DATETIME的空間利用率更高。 4.DATETIME的默認(rèn)值為null;TIMESTAMP的字段默認(rèn)不為空(not null),默認(rèn)值為當(dāng)前時(shí)間(CURRENT_TIMESTAMP),如果不做特殊處理,并且update語句中沒有指定該列的更新值,則默認(rèn)更新為當(dāng)前時(shí)間。 ============注意啦,注意啦,注意啦=========== 1. 單獨(dú)插入時(shí)間時(shí),需要以字符串的形式,按照對(duì)應(yīng)的格式插入 2. 插入年份時(shí),盡量使用4位值 3. 插入兩位年份時(shí), <=69,以20開頭,比如50, 結(jié)果2050 >=70,以19開頭,比如71,結(jié)果1971 MariaDB [db1]> create table t12(y year); MariaDB [db1]> insert into t12 values -> (50), -> (71); MariaDB [db1]> select * from t12; +--------+ | y? ? ? ? | +--------+ | 2050 | | 1971 | +---------+
數(shù)據(jù)類型之字符型 字符型 分類 char 定長(zhǎng)字符 varchar 變長(zhǎng)字符 char類型的長(zhǎng)度是固定 無論你存儲(chǔ)的數(shù)據(jù)有多長(zhǎng) 占用的容量都一樣 char(3) 存儲(chǔ)的數(shù)據(jù)為 "a" 在硬盤保存的數(shù)據(jù)還是占3字符長(zhǎng)度 實(shí)際保存的是"a " 如果是char類型 如果你的數(shù)據(jù)不足指定長(zhǎng)度 就在后面用空格補(bǔ)全 varchar 長(zhǎng)度是可變的 存儲(chǔ)的數(shù)據(jù)有多長(zhǎng)就占用多長(zhǎng) varchar(3) 存儲(chǔ)的數(shù)據(jù)為 "a" 在硬盤保存的數(shù)據(jù)還是占1字符長(zhǎng)度 實(shí)際保存的是"a" yxx exx lxx zxx cx wxx char(3) 因?yàn)槭强勺冮L(zhǎng)度,就有一個(gè)問題,不知道數(shù)據(jù)從哪里開始到哪里結(jié)束,所以需要有一個(gè)位置保存數(shù)據(jù)的長(zhǎng)度 如果真實(shí)的數(shù)據(jù)<255bytes則需要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數(shù)字為255) 如果真實(shí)的數(shù)據(jù)>255bytes則需要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數(shù)字為65535) 驗(yàn)證: 使用一個(gè) char_length的函數(shù) 可以查看字符的長(zhǎng)度 create table t18(a char(4),b varchar(4)); insert into t18 value("x","x"); select char_length(a),char_length(b) from t18; #char_length()方法可以獲取數(shù)據(jù)庫(kù)內(nèi),字符的長(zhǎng)度。 兩個(gè)字段的長(zhǎng)度都為1 結(jié)論: 這是因?yàn)?mysql在存儲(chǔ)時(shí) 自動(dòng)加上的空格 對(duì)使用者而言是沒有意義的 所以mysql自動(dòng)幫你處理掉空格了 我們可以設(shè)置sql模式 來讓它現(xiàn)出原形 set global sql_mode = "PAD_CHAR_TO_FULL_LENGTH,STRICT_TRANS_TABLES" 設(shè)置完成后重啟msyql 再次查詢長(zhǎng)度 注意: 當(dāng)你在執(zhí)行這樣的查詢語句時(shí) mysql會(huì)自動(dòng)將參數(shù)末尾的空格去除 select * from t19 where name = "yh" 當(dāng)你在使用模糊搜索時(shí) 要注意 定長(zhǎng)字符 后面可能會(huì)有空格 所以最好在后面加上百分號(hào) % select *from t19 where name like "yh"; % 任意個(gè)數(shù)的任意字符 _ 1個(gè)任意字符 如何選擇 char 存取效率高 浪費(fèi)存儲(chǔ)空間 varchar 存取效率低于char 節(jié)省存儲(chǔ)空間 使用起來感受不到區(qū)別 通常用的是char ====================================== char 和varchar的比較 #char類型:定長(zhǎng),簡(jiǎn)單粗暴,浪費(fèi)空間,存取速度快字符長(zhǎng)度范圍:0-255(一個(gè)中文是一個(gè)字符,是utf8編碼的3個(gè)字節(jié)) 存儲(chǔ): 存儲(chǔ)char類型的值時(shí),會(huì)往右填充空格來滿足長(zhǎng)度 例如:指定長(zhǎng)度為10,存>10個(gè)字符則報(bào)錯(cuò),存<10個(gè)字符則用空格填充直到湊夠10個(gè)字符存儲(chǔ) 檢索: 在檢索或者說查詢時(shí),查出的結(jié)果會(huì)自動(dòng)刪除尾部的空格,除非我們打開pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)#varchar類型:變長(zhǎng),精準(zhǔn),節(jié)省空間,存取速度慢字符長(zhǎng)度范圍:0-65535(如果大于21845會(huì)提示用其他類型 。mysql行最大限制為65535字節(jié),字符編碼為utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html) 存儲(chǔ): varchar類型存儲(chǔ)數(shù)據(jù)的真實(shí)內(nèi)容,不會(huì)用空格填充,如果'ab ',尾部的空格也會(huì)被存起來 強(qiáng)調(diào):varchar類型會(huì)在真實(shí)數(shù)據(jù)前加1-2Bytes的前綴,該前綴用來表示真實(shí)數(shù)據(jù)的bytes字節(jié)數(shù)(1-2Bytes最大表示65535個(gè)數(shù)字,正好符合mysql對(duì)row的最大字節(jié)限制,即已經(jīng)足夠使用) 如果真實(shí)的數(shù)據(jù)<255bytes則需要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數(shù)字為255) 如果真實(shí)的數(shù)據(jù)>255bytes則需要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數(shù)字為65535) 檢索: 尾部有空格會(huì)保存下來,在檢索或者說查詢時(shí),也會(huì)正常顯示包含空格在內(nèi)的內(nèi)容 =========================================================== =========================================================== 大文本類型: TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT 文本是帶有編碼 BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB 也是字符數(shù)據(jù) 但是不帶編碼 二進(jìn)制類型: 用于存儲(chǔ)多媒體數(shù)據(jù) 比如視頻 但是我們一般不會(huì)將多媒體數(shù)據(jù)存到數(shù)據(jù) 而是存儲(chǔ)文件路徑地址 BINARY系列 BINARY VARBINARY 存儲(chǔ)二進(jìn)制數(shù)據(jù)
數(shù)據(jù)類型之枚舉和集合 枚舉 ** 用于描述 一個(gè)已知范圍的數(shù)據(jù) 例如性別: 只有男 女 或其他 enum("man","woman","other") 總結(jié): 枚舉中只能是字符串類型 添加的數(shù)據(jù)只能是已經(jīng)出現(xiàn)在枚舉中的值 你的值只能是其中的一個(gè) 你也可以使用枚舉值的序號(hào)來插入值 從1開始 集合? 用于描述一堆數(shù)據(jù) 比如你的興趣愛好 set("watch movie","listen music","play game") 總結(jié):集合中的數(shù)據(jù) 只能是字符串 添加的數(shù)據(jù)只能是已經(jīng)出現(xiàn)在集合中的值 你的值可以是其中的任意一個(gè)或多個(gè) 你也可以使用枚舉值的序號(hào)來插入值 從1開始 但是只能給一個(gè)序號(hào) posted on 2018-12-27 09:28 漫天飛雪世情難卻 閱讀(...) 評(píng)論(...) ?編輯 收藏
數(shù)據(jù)類型之整數(shù)型 數(shù)據(jù)類型 為什么需要將數(shù)據(jù)分類? 1.為了描述事物 更加準(zhǔn)確 2.描述起來更方便 3.節(jié)省內(nèi)存空間 1 a 你 utf8 下 5個(gè)字節(jié) 1 a b c unicode 6個(gè)字節(jié) mysql支持的數(shù)據(jù)類型: 整型 ***? ? ? ? ?***? ? ? ? ? ? ?***? ? ? ? ? *****? ? ?*** tinyint smallint mediumint? ? ?int? ?bigint 字節(jié)數(shù): 1? ? ? ?2? ? ? ? ? ? ? 3? ? ? ? ? ? ? ? 4? ? ? ?8 默認(rèn)情況下整型是有符號(hào)的 需要用一個(gè)二進(jìn)制位存儲(chǔ)符號(hào) 給整型加上 約束 unsigned來表示無符號(hào) 如果數(shù)據(jù)超出范圍就盡可能保存最大的 例如 在無符號(hào)下 保存256 其實(shí)存的255 如果有符號(hào) 例如 tinyint 保存-1280 其實(shí)存的是-128 是最小值 ======================================== tinyint[(m)] [unsigned] [zerofill] m為顯示的長(zhǎng)度,不寫默認(rèn)為3。 小整數(shù)(一個(gè)字節(jié),也就是8個(gè)比特位),數(shù)據(jù)類型用于保存一些范圍的整數(shù) 數(shù)值范圍: 有符號(hào): -128 ~ 127 無符號(hào): 0 ~ 255 PS: MySQL中無布爾值,使用tinyint(1)構(gòu)造。 ======================================== int[(m)][unsigned][zerofill] m為顯示的長(zhǎng)度,不寫默認(rèn)為10。 整數(shù)(4個(gè)字節(jié),也就是32個(gè)比特位),數(shù)據(jù)類型用于保存一些范圍的整數(shù) 數(shù)值范圍: 有符號(hào): -2147483648 ~?2147483647 無符號(hào): 0 ~ 4294967295(2 ** 32 -1) ======================================== bigint[(m)][unsigned][zerofill] 大整數(shù),數(shù)據(jù)類型用于保存一些范圍的整數(shù) 數(shù)值范圍: 有符號(hào): -9223372036854775808 ~ 9223372036854775807 無符號(hào): 0 ~ 18446744073709551615 修改嚴(yán)格模式: 以上特性的出現(xiàn)是因?yàn)?mysql處于非嚴(yán)格模式 查看當(dāng)前模式 show variables like "sql_mode"; 修改為嚴(yán)格模式 set global sql_mode = "STRICT_TRANS_TABLES"; 嚴(yán)格模式下 如果值超出范圍就直接報(bào)錯(cuò),在一些版本中默認(rèn)就是嚴(yán)格模式! 在我們的正常開發(fā)中,我們應(yīng)該先判斷數(shù)據(jù)的正確性,沒有問題在發(fā)給數(shù)據(jù)庫(kù) 怎么選擇: 得根據(jù)實(shí)際情況來判斷,能夠保存你的數(shù)據(jù)的最小類型 長(zhǎng)度限制對(duì)于整型的意義: create table t10(id int(1)); insert into t10 value(454555); select *from t10; 發(fā)現(xiàn)這個(gè)數(shù)也存儲(chǔ)成功 說明 這里長(zhǎng)度指的不是存儲(chǔ)容量限制 而是顯示的寬度 如果你的數(shù)據(jù)超過了顯示寬度 有幾個(gè)顯示幾個(gè) 如果不足 則補(bǔ)全到指定長(zhǎng)度 得告訴它用什么來補(bǔ)全 create table t13(id int(10) zerofill);(zerofill用零補(bǔ)) 總結(jié) : 這個(gè)10,不是容量限制 而是 顯示寬度 要限制顯示寬度 1.創(chuàng)建表時(shí) 給整型加上寬度 2.加上zerofill約束
數(shù)據(jù)類型之浮點(diǎn)型 浮點(diǎn)型: 小數(shù)型 分類: float ***** double **** decimal ***** 字節(jié)數(shù): 4 8 不確定(手動(dòng)指定) 給浮點(diǎn)設(shè)置寬度限制 float(m,d) #m的最大值為255,d的最大值為30,精度最小 double(m,d) #m的最大值為255,d的最大值為30,精度中等 decimal(m,d) #m的最大值為65,d的最大值為30,精度最高 長(zhǎng)度說明 ***** m表示 這個(gè)浮點(diǎn)數(shù)整體的長(zhǎng)度 d表示 小數(shù)部分的長(zhǎng)度 例如: float(5,3) 最大值: 99.999 區(qū)別 ***** 相同點(diǎn): 小數(shù)部分最大長(zhǎng)度都是30 float和double的最大長(zhǎng)度為255 不同點(diǎn): decimal的整體最大長(zhǎng)度65 精度不同 double 比 float 精度高 decimal 是準(zhǔn)確的 不會(huì)丟失精度 如何選擇:你對(duì)精確度要求高你就使用 decimal 例子: 可以看到float的精度幾乎只有double的一半,decimal的精度最高,一點(diǎn)都沒有出錯(cuò)。
數(shù)據(jù)類型之時(shí)間類型 分類 time 時(shí)分秒 HH:MM:SS *** year 年份 *** date 日期 年月日 *** datetime 日期加時(shí)間 年月日 時(shí)分秒 年份最大是9999 ***** timestamp 時(shí)間戳 從1970-1-1開始算 年份最大是2037 ***** TIME HH:MM:SS('-838:59:59'/'838:59:59') YEAR YYYY(1901/2155) DATE YYYY-MM-DD(1000-01-01/9999-12-31) DATETIME YYYY-MM-DD HH:MM:SS(1000-01-01 00:00:00/9999-12-31 23:59:59 ) TIMESTAMP YYYYMMDD HHMMSS(1970-01-01 00:00:00/2037 年某時(shí)) 共同點(diǎn): 時(shí)間的存取通過字符串類型 都可以使用now()函數(shù)來插入當(dāng)前時(shí)間 datetime不寫now()方法時(shí),默認(rèn)插入為空 datetime 和 時(shí)間戳都能夠表示日期和時(shí)間 不同之處是: 年份最大范圍不同 時(shí)間戳可以為空 代表當(dāng)前時(shí)間,如圖: 時(shí)間戳在你更新記錄時(shí) 會(huì)自動(dòng)更新為當(dāng)前時(shí)間,如圖: 在實(shí)際應(yīng)用的很多場(chǎng)景中,MySQL的這兩種日期類型都能夠滿足我們的需要,存儲(chǔ)精度都為秒,但在某些情況下,會(huì)展現(xiàn)出他們各自的優(yōu)劣。下面就來總結(jié)一下兩種日期類型的區(qū)別。 1.DATETIME的日期范圍是1001——9999年,TIMESTAMP的時(shí)間范圍是1970——2038年。 2.DATETIME存儲(chǔ)時(shí)間與時(shí)區(qū)無關(guān),TIMESTAMP存儲(chǔ)時(shí)間與時(shí)區(qū)有關(guān),顯示的值也依賴于時(shí)區(qū)。在mysql服務(wù)器,操作系統(tǒng)以及客戶端連接都有時(shí)區(qū)的設(shè)置。 3.DATETIME使用8字節(jié)的存儲(chǔ)空間,TIMESTAMP的存儲(chǔ)空間為4字節(jié)。因此,TIMESTAMP比DATETIME的空間利用率更高。 4.DATETIME的默認(rèn)值為null;TIMESTAMP的字段默認(rèn)不為空(not null),默認(rèn)值為當(dāng)前時(shí)間(CURRENT_TIMESTAMP),如果不做特殊處理,并且update語句中沒有指定該列的更新值,則默認(rèn)更新為當(dāng)前時(shí)間。 ============注意啦,注意啦,注意啦=========== 1. 單獨(dú)插入時(shí)間時(shí),需要以字符串的形式,按照對(duì)應(yīng)的格式插入 2. 插入年份時(shí),盡量使用4位值 3. 插入兩位年份時(shí), <=69,以20開頭,比如50, 結(jié)果2050 >=70,以19開頭,比如71,結(jié)果1971 MariaDB [db1]> create table t12(y year); MariaDB [db1]> insert into t12 values -> (50), -> (71); MariaDB [db1]> select * from t12; +--------+ | y? ? ? ? | +--------+ | 2050 | | 1971 | +---------+
數(shù)據(jù)類型之字符型 字符型 分類 char 定長(zhǎng)字符 varchar 變長(zhǎng)字符 char類型的長(zhǎng)度是固定 無論你存儲(chǔ)的數(shù)據(jù)有多長(zhǎng) 占用的容量都一樣 char(3) 存儲(chǔ)的數(shù)據(jù)為 "a" 在硬盤保存的數(shù)據(jù)還是占3字符長(zhǎng)度 實(shí)際保存的是"a " 如果是char類型 如果你的數(shù)據(jù)不足指定長(zhǎng)度 就在后面用空格補(bǔ)全 varchar 長(zhǎng)度是可變的 存儲(chǔ)的數(shù)據(jù)有多長(zhǎng)就占用多長(zhǎng) varchar(3) 存儲(chǔ)的數(shù)據(jù)為 "a" 在硬盤保存的數(shù)據(jù)還是占1字符長(zhǎng)度 實(shí)際保存的是"a" yxx exx lxx zxx cx wxx char(3) 因?yàn)槭强勺冮L(zhǎng)度,就有一個(gè)問題,不知道數(shù)據(jù)從哪里開始到哪里結(jié)束,所以需要有一個(gè)位置保存數(shù)據(jù)的長(zhǎng)度 如果真實(shí)的數(shù)據(jù)<255bytes則需要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數(shù)字為255) 如果真實(shí)的數(shù)據(jù)>255bytes則需要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數(shù)字為65535) 驗(yàn)證: 使用一個(gè) char_length的函數(shù) 可以查看字符的長(zhǎng)度 create table t18(a char(4),b varchar(4)); insert into t18 value("x","x"); select char_length(a),char_length(b) from t18; #char_length()方法可以獲取數(shù)據(jù)庫(kù)內(nèi),字符的長(zhǎng)度。 兩個(gè)字段的長(zhǎng)度都為1 結(jié)論: 這是因?yàn)?mysql在存儲(chǔ)時(shí) 自動(dòng)加上的空格 對(duì)使用者而言是沒有意義的 所以mysql自動(dòng)幫你處理掉空格了 我們可以設(shè)置sql模式 來讓它現(xiàn)出原形 set global sql_mode = "PAD_CHAR_TO_FULL_LENGTH,STRICT_TRANS_TABLES" 設(shè)置完成后重啟msyql 再次查詢長(zhǎng)度 注意: 當(dāng)你在執(zhí)行這樣的查詢語句時(shí) mysql會(huì)自動(dòng)將參數(shù)末尾的空格去除 select * from t19 where name = "yh" 當(dāng)你在使用模糊搜索時(shí) 要注意 定長(zhǎng)字符 后面可能會(huì)有空格 所以最好在后面加上百分號(hào) % select *from t19 where name like "yh"; % 任意個(gè)數(shù)的任意字符 _ 1個(gè)任意字符 如何選擇 char 存取效率高 浪費(fèi)存儲(chǔ)空間 varchar 存取效率低于char 節(jié)省存儲(chǔ)空間 使用起來感受不到區(qū)別 通常用的是char ====================================== char 和varchar的比較 #char類型:定長(zhǎng),簡(jiǎn)單粗暴,浪費(fèi)空間,存取速度快字符長(zhǎng)度范圍:0-255(一個(gè)中文是一個(gè)字符,是utf8編碼的3個(gè)字節(jié)) 存儲(chǔ): 存儲(chǔ)char類型的值時(shí),會(huì)往右填充空格來滿足長(zhǎng)度 例如:指定長(zhǎng)度為10,存>10個(gè)字符則報(bào)錯(cuò),存<10個(gè)字符則用空格填充直到湊夠10個(gè)字符存儲(chǔ) 檢索: 在檢索或者說查詢時(shí),查出的結(jié)果會(huì)自動(dòng)刪除尾部的空格,除非我們打開pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)#varchar類型:變長(zhǎng),精準(zhǔn),節(jié)省空間,存取速度慢字符長(zhǎng)度范圍:0-65535(如果大于21845會(huì)提示用其他類型 。mysql行最大限制為65535字節(jié),字符編碼為utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html) 存儲(chǔ): varchar類型存儲(chǔ)數(shù)據(jù)的真實(shí)內(nèi)容,不會(huì)用空格填充,如果'ab ',尾部的空格也會(huì)被存起來 強(qiáng)調(diào):varchar類型會(huì)在真實(shí)數(shù)據(jù)前加1-2Bytes的前綴,該前綴用來表示真實(shí)數(shù)據(jù)的bytes字節(jié)數(shù)(1-2Bytes最大表示65535個(gè)數(shù)字,正好符合mysql對(duì)row的最大字節(jié)限制,即已經(jīng)足夠使用) 如果真實(shí)的數(shù)據(jù)<255bytes則需要1Bytes的前綴(1Bytes=8bit 2**8最大表示的數(shù)字為255) 如果真實(shí)的數(shù)據(jù)>255bytes則需要2Bytes的前綴(2Bytes=16bit 2**16最大表示的數(shù)字為65535) 檢索: 尾部有空格會(huì)保存下來,在檢索或者說查詢時(shí),也會(huì)正常顯示包含空格在內(nèi)的內(nèi)容 =========================================================== =========================================================== 大文本類型: TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT 文本是帶有編碼 BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB 也是字符數(shù)據(jù) 但是不帶編碼 二進(jìn)制類型: 用于存儲(chǔ)多媒體數(shù)據(jù) 比如視頻 但是我們一般不會(huì)將多媒體數(shù)據(jù)存到數(shù)據(jù) 而是存儲(chǔ)文件路徑地址 BINARY系列 BINARY VARBINARY 存儲(chǔ)二進(jìn)制數(shù)據(jù)
數(shù)據(jù)類型之枚舉和集合 枚舉 ** 用于描述 一個(gè)已知范圍的數(shù)據(jù) 例如性別: 只有男 女 或其他 enum("man","woman","other") 總結(jié): 枚舉中只能是字符串類型 添加的數(shù)據(jù)只能是已經(jīng)出現(xiàn)在枚舉中的值 你的值只能是其中的一個(gè) 你也可以使用枚舉值的序號(hào)來插入值 從1開始 集合? 用于描述一堆數(shù)據(jù) 比如你的興趣愛好 set("watch movie","listen music","play game") 總結(jié):集合中的數(shù)據(jù) 只能是字符串 添加的數(shù)據(jù)只能是已經(jīng)出現(xiàn)在集合中的值 你的值可以是其中的任意一個(gè)或多個(gè) 你也可以使用枚舉值的序號(hào)來插入值 從1開始 但是只能給一個(gè)序號(hào) posted on 2018-12-27 09:28 漫天飛雪世情難卻 閱讀(...) 評(píng)論(...) ?編輯 收藏
轉(zhuǎn)載于:https://www.cnblogs.com/jokezl/articles/10183133.html
總結(jié)
以上是生活随笔為你收集整理的数据库之存储引擎,数据类型-30的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: MYSQL 5.6安装设置中英文翻译
- 下一篇: DOM4J解析XML文档、Documen