MySQL數據類型--字符串類型


字符串類型是在數據庫中存儲字符串的數據類型,字符串類型包括char,varchar,text,enum和set。

OK,我們來一個一個的看下上面提到的幾種類型。

  • char類型和varchar類型

char類型和varchar類型都是在創建表時指定了最大長度,其基本形式如下:字符串類型(M)。其中,字符串類型參數指定了數據類型是char類型還是varchar類型,M參數指定了該字符串的最大長度爲M。舉個例子,char(4)就是指數據類型是char類型,其最大長度爲4。

char類型的長度是固定的,在創建表時就指定了,其長度可以是0~~255的任意值。

比如,char(100)就是指定char類型的長度爲100。

varchar類型的長度是可變的,在創建表時指定了最大長度。定義時,其最大值可以取0~~65525之間的任意值。指定了varchar類型的最大值以後,其長度可以在o到最大長度之間。

比如,varchar(100)的最大長度是100,但是,不是每條記錄都要佔用100個字節。而是在這個最大值範圍內,使用多少分配多少,varchar類型實際佔用的空間爲字符串的實際長度加一。這樣,即可有效節約系統的空間。

現在我們在這裏舉一個例子,我們向char(5)和varchar(5)中存入不同長度的字符串。現在我們將數據庫中的存儲形式和佔用的字節數進行對比,如下圖。


關於上圖的解釋:

1,不管我們插入的字符串是什麼樣子,char(5)所佔用的空間都是5個字節。我們前面也說過了,char類型的長度固定

2,varchar(5)所佔的字節數是實際長度的基礎上加1。因爲字符串的結束標識符佔用了一個字節呢。比如說上表中的第四行,varchar將字符串‘123 ’最後面的空格依然保留着。

爲了確認下空格是否保留,我們現在將數據後面模擬加上‘*’字符,然後來實際操作下數據庫中的char類型和varchar類型。建表語句如下:
CREATE TABLE `linkinframe`.`test` (
  `id` INT NOT NULL,
  `a` CHAR(5) NULL,
  `b` VARCHAR(5) NULL,
  PRIMARY KEY (`id`));
現在我們往數據庫中插入幾條數據:
INSERT INTO `linkinframe`.`test` (`id`, `a`, `b`) VALUES ('1','','');
INSERT INTO `linkinframe`.`test` (`id`, `a`, `b`) VALUES ('2','1','1');
INSERT INTO `linkinframe`.`test` (`id`, `a`, `b`) VALUES ('3','123','123');
INSERT INTO `linkinframe`.`test` (`id`, `a`, `b`) VALUES ('4','123 ','123 ');
INSERT INTO `linkinframe`.`test` (`id`, `a`, `b`) VALUES ('5','12345','12345');
INSERT INTO `linkinframe`.`test` (`id`, `a`, `b`) VALUES ('6','1234567','1234567');
模擬數據庫數據顯示如下:


總結:上面的實踐證明了一個結論,varchar類型將‘123 ’最後面的空格保留着,而char類型中‘123 ’後面的空格自動刪除啦。


char類型和varchar類型是我們最爲常用的2種字符串類型,關於這2種類型有如下2點特殊說明:

1,如果插入的字符串的長度已經大於了可以插入的最大值,那麼這個時候數據庫會報錯,說data too long for column。
比如說,現在我們定義2個char類型和varchar類型的字段,長度都爲5,但是我們插入的值是‘123456’,那麼系統就會阻止這個值的插入然後報錯。
關於插入的字符串長度大於數據定義的長度這個問題,資料上是上面這麼說的,然後平時編碼中使用ORM的時候也明確的遇見過這個錯誤。
但是我實際sql實踐中,比如上面的插入數據庫中的最後一條數據,數據庫做了截取操作,並沒有報錯,而是一個警告,控制檯輸出如下:

Data truncated for column 'a' at row 1。 Data truncated for column 'b' at row 1

2,我們定義長度的時候定義的數據長度,定義的長度就是字符串最大的長度,舉個例子,我定義一個name字段,varchar(6),那麼該字段最多可以容納6個漢字。
這點別和Oracle的varchar2類型的字段搞混淆了。Oracle中的字符串類型2個字節表示一個漢字。
舉個例子,還是上面的建表語句,現在往其中插入一條字符串的數據,一個超過了字符串定義的長度5,一個沒有超過,結果超過的字符串被截斷啦。
INSERT INTO `linkinframe`.`test` (`id`, `a`, `b`) VALUES ('6','我愛你','我愛你我愛你');

數據庫現在顯示如下:




  • text類型
text類型是一種特殊的字符串類型。text只能保存字符數據,如新聞的內容等。

text類型包括tinytext,text,mediumtext,longtext。現在將從4種text類型允許的長度和存儲空間進行對比,如下圖:


text類型總結:

這種字符串類型實際中使用並不是太多,一般用來直接存儲一個比較大的文本,比如說一篇文章,一篇新聞。

從上圖也可以看出,各種text類型的區別在於允許的長度和存儲空間不同。因此在這幾種text類型中,根據需求選取技能滿足需要又能節約空間的類型即可。

  • enum類型
enum類型又稱爲枚舉類型,在創建表時,enum類型的取值範圍就以列表的形式指定了。其基本形式如下:屬性名 enum('值1','值2',...,'值n'),其中屬性名參數指定字段的名稱,‘值n’參數表示列表中的第n個值,這些值末尾的空格將會被系統直接刪除。注意:

1,enum類型的值只能去列表中的一個元素,其取值列表中最多只能有65535個值。列表中的每個值都有一個順序排列的編號,MySQL中存入的是這個編號,而不是列表中的值。
2,如果enum類型加上了not null屬性,其默認值爲取值列表中的第一個元素。如果不加not null屬性,enum類型將允許插入null,而且null爲默認值。

OK,現在我們來實際模擬下MySQL中這種數據類型。

建表語句如下:

CREATE TABLE `linkinframe`.`test` (
  `id` INT NOT NULL,
  `a` ENUM('man', 'woman') NULL,
  PRIMARY KEY (`id`));
現在我們往數據庫中插入幾條數據:
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('1', 'man');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('2', 'woman');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('3', null);
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('4', '2');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('5', '1');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('6', 'huhu');
現在數據庫顯示如下:




OK,關於enum類型的總結:

1,使用enum類型,數據庫中實際存儲的每個枚舉的編號,而不是列表中的值,所以我們也可以直接插入每個枚舉的編號。
2,實際的實踐中,如果我沒有在該not null的枚舉值上面插入值,或者是隨便插入一個值,數據庫存儲的都爲空。
3,實際存儲中,如果只能選取列表中的一個值,就選擇enum類型,如果需要選取列表中多個值的組合,就需要選擇set類型。

  • set類型
上面也說到了,如果需要選取列表中多個值的組合,就要選擇set類型。在創建表時,set類型的取值範圍就以列表的形式指定了。其基本形式如下:屬性名 set('值1','值2',....,'值n')。其中,‘屬性名’屬性指定字段的名稱,‘值n’參數表示列表中的第n個值,這些值末尾的空格將會被系統直接刪除。其基本形式與enum類型一樣。注意:

1,set類型的值可以去列表中的一個元素或者多個元素的組合。去多個元素時,不同元素之間用逗號隔開。set類型的值最多只能有64個元素構成。

2,同enum類型一樣,列表中的每個值都有一個順序排列的編號,MySQL中實際存儲的是這個編號,而不是列表中的值。

3,插入記錄時,set字段中的元素順序無關緊要,存入MySQL數據庫後,數據庫系統會自動按照定義時的順序顯示。OK,現在我們來實際操作下數據庫這種數據類型:
建表語句如下:

CREATE TABLE `linkinframe`.`test` (
  `id` INT NOT NULL,
  `a` SET('a', 'b', 'c', 'd') NOT NULL,
  PRIMARY KEY (`id`));
插入幾條語句:
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('1', 'a');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('2', 'c');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('3', 'a,b');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('4', 'a,b,c,d');
INSERT INTO `linkinframe`.`test` (`id`, `a`) VALUES ('5', 'a,e');
數據庫顯示如下:


關於set類型的總結:

1,set類型和enum類型對於取值在一定範圍的離散值很有效。enum類型只能在取值列表中取一個值,set類型可以在取值列表中去多個值。

2,這兩種類型的數據都不是直接將數據存入數據庫,而是將其列表中的編號存入數據庫。

3,資料中說如果隨便往這2種類型中插入數據,會報錯,但是我自己的實踐中並沒有報錯,而是插入一個null。

4,對於set的話,如果插入多個值,其中有些值合法,有些值不合法,那麼只會將合法的插入進去,不合法的不做處理。


發佈了284 篇原創文章 · 獲贊 66 · 訪問量 71萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章