MySQL 5.6 創建數據表時出現1071錯誤,緣由分析及解決辦法

零、問題的背景


在初學SpringBoot + Angular時,數據庫軟件依然使用的MySQL,不一樣之處在於,此次的MySQL服務再也不使用XAMPP搭建,而使用了更加方便的Docker來提供服務。html


1、問題復現


在配置數據庫時,用Docker搭建好環境以後,開始創建第一張數據表
圖片.png
而後按照教程中的查詢語句新建查詢
(教程地址:https://www.kancloud.cn/yunzh...mysql

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT '' COMMENT '姓名',
  `sex` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0男,1女',
  `username` varchar(255) NOT NULL COMMENT '用戶名',
  `email` varchar(255) DEFAULT '' COMMENT '郵箱',
  `create_time` bigint(11) unsigned NOT NULL DEFAULT '0' COMMENT '建立時間',
  `update_time` bigint(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新時間',
  PRIMARY KEY (`id`),
  UNIQUE KEY `nx1HkMqiUveGnJz5lHE7mEcFI5WVew3iXbv3HCwF` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of teacher
-- ----------------------------
BEGIN;
INSERT INTO `teacher` VALUES (1, '張三', 1, 'zhangsan', 'zhangsan@mail.com', 1569721598000, 1569721598000);
INSERT INTO `teacher` VALUES (2, '李四', 0, 'lisi', 'lisi@yunzhi.club', 1569721598000, 1569721598000);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

將代碼複製到查詢窗口
圖片.png
卻出現了以下提示:
1071 - Specified key was too long; max key length is 767 bytes, Time: 0.001000s
圖片.png
按照慣例,遇到報錯先翻譯
錯誤信息爲:「指定的關鍵字太長;最大關鍵字長度爲767字節spring


2、產生緣由


查閱資料後,在一篇博客中發現:sql

若是啓用了系統變量innodb_large_prefix(MySQL 5.6.41,默認是關閉的,MySQL 5.7默認開啓),則對於使用DYNAMIC或COMPRESSED行格式的InnoDB表,索引鍵前綴限制爲3072字節。若是禁用innodb_large_prefix,則對於任何行格式的表,索引鍵前綴限制爲767字節。嘗試使用超出限制的索引鍵前綴長度會返回錯誤。
注意:上面是767個字節,而不是字符,具體到字符數量,這就跟字符集有關。GBK是雙字節的,UTF-8是三字節的
(引用自:https://www.cnblogs.com/kerry...數據庫

那麼緣由就很好分析了,教程中的數據表是utf8mb4,是四字節的,再看數據表中最長的字段,長度爲255,255 * 4 = 1020 > 767,所以纔會報錯。springboot

`username` varchar(255) NOT NULL COMMENT '用戶名',
  `email` varchar(255) DEFAULT '' COMMENT '郵箱',

3、解決方法


一、減少字段長度

當了解原理以後,最早想到的就是嘗試減少字段長度,來驗證理論的正確性。ide

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `id` bigint(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(128) DEFAULT '' COMMENT '姓名',
  `sex` tinyint(1) unsigned NOT NULL DEFAULT '0' COMMENT '0男,1女',
  `username` varchar(128) NOT NULL COMMENT '用戶名',
  `email` varchar(128) DEFAULT '' COMMENT '郵箱',
  `create_time` bigint(11) unsigned NOT NULL DEFAULT '0' COMMENT '建立時間',
  `update_time` bigint(11) unsigned NOT NULL DEFAULT '0' COMMENT '更新時間',
  PRIMARY KEY (`id`),
  UNIQUE KEY `nx1HkMqiUveGnJz5lHE7mEcFI5WVew3iXbv3HCwF` (`username`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

-- ----------------------------
-- Records of teacher
-- ----------------------------
BEGIN;
INSERT INTO `teacher` VALUES (1, '張三', 1, 'zhangsan', 'zhangsan@mail.com', 1569721598000, 1569721598000);
INSERT INTO `teacher` VALUES (2, '李四', 0, 'lisi', 'lisi@yunzhi.club', 1569721598000, 1569721598000);
COMMIT;

SET FOREIGN_KEY_CHECKS = 1;

把全部的255都減半,改成128, 128 * 4 = 512 < 767
再次運行查詢語句以後,順利經過。測試

二、將MySQL版本升級到5.7以上

圖片.png
我分別在MySQL5.六、5.七、Latest版本上運行了這段查詢語句。經測試,5.7和Latest版本均不存在此問題,說明5.7以上版本確實默認開啓了innodb_large_prefix。
圖片.pngui

三、手動開啓innodb_large_prefix

須要知足下面幾個條件(參考https://www.cnblogs.com/kerry...):
1: 系統變量innodb_large_prefix爲ON
2: 系統變量innodb_file_format爲Barracuda
3: ROW_FORMAT爲DYNAMIC或COMPRESSEDspa


4、總結


一、版本

圖片.png
教程中提到,MySQL使用5.6版本和5.7版本,並無影響,事實上此次發現的問題,說明了不一樣版本的MySQL仍是有許多區別的。

二、XAMPP內置的MySQL和MariaDB

那麼,在以前使用XAMPP時,使用的應該就是MySQL5.6啊,爲何沒有出現這個錯誤呢?
圖片.png
去XAMPP官網上面一看,才忽然發現,如今的XAMPP集成的並非MySQL,而是早就換成了它的分支——MariaDB!

圖片.png
但是,新版的軟件裏面寫着的,就是MySQL啊?
抱着刨根問底的態度,我打開了XAMPP的控制檯,在命令行中輸入mysql
圖片.png結果證明了,確實換成了MariaDB!。

相關文章
相關標籤/搜索