1、问题描述

前两天在群里看到同事反馈一个空格问题,大致现象如下:

  1. mysql> select @@version;
  2. +-----------+
  3. | @@version |
  4. +-----------+
  5. | 8.0.25 |
  6. +-----------+
  7. 1 row in set (0.00 sec)
  8. mysql> create table t1(
  9. -> c1 int,
  10. -> c2 varchar(4) check(c2<>'') #单引号之间无空格
  11. -> )engine=innodb;
  12. Query OK, 0 rows affected (0.21 sec)
  13. mysql> insert into t1 select 1,' '; #c2字段插入两个空格
  14. ERROR 3819 (HY000): Check constraint 't1_chk_1' is violated.

check定义c2<>'',往c2字段插入空格,提示违反check约束。

为什么insert语句中的' '(单引号之间有一个或多个空格)会被判断为''(单引号之间无空格),导致插入失败?

2、涉及知识

2.1、Stored and Retrieved

https://dev.mysql.com/doc/refman/8.0/en/char.html

When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed unless the PAD_CHAR_TO_FULL_LENGTH SQL mode is enabled.

VARCHAR values are not padded when they are stored. Trailing spaces are retained when values are stored and retrieved, in conformance with standard SQL.

CHAR(N):当插入的字符数小于N,它会在字符串的右边补充空格,直到总字符数达到N再进行存储;当查询返回数据时默认会将字符串尾部的空格去掉,除非SQL_MODE设置PAD_CHAR_TO_FULL_LENGTH(手册显示8.0.13 deprecated,8.0.25还能使用)。

VARCHAR(N):当插入的字符数小于N,它不会在字符串的右边补充空格,insert内容原封不动的进行存储;如果原本字符串右边有空格,在存储和查询返回时都会保留空格。

2.2、Collation Pad Attribute

https://dev.mysql.com/doc/refman/8.0/en/char.html

Values in CHAR, VARCHAR, and TEXT columns are sorted and compared according to the character set collation assigned to the column.

MySQL collations have a pad attribute of PAD SPACE, other than Unicode collations based on UCA 9.0.0 and higher, which have a pad attribute of NO PAD.

对于CHAR、VARCHAR、TEXT字段,排序和比较运算依赖字段上的Collation,Collation的Pad属性控制字符串尾部空格处理方式。

可以通过INFORMATION_SCHEMA.COLLATIONS表,查看Collation所使用的Pad属性:

  1. mysql> select collation_name,pad_attribute from information_schema.collations;
  2. +----------------------------+---------------+
  3. | collation_name | pad_attribute |
  4. +----------------------------+---------------+
  5. | armscii8_general_ci | PAD SPACE |
  6. ...
  7. | utf8mb4_0900_bin | NO PAD |
  8. +----------------------------+---------------+
  9. 272 rows in set (0.01 sec)

2.3、Trailing Space Handling in Comparisons

https://dev.mysql.com/doc/refman/8.0/en/charset-binary-collations.html#charset-binary-collations-trailing-space-comparisons

For nonbinary strings (CHAR, VARCHAR, and TEXT values), the string collation pad attribute determines treatment in comparisons of trailing spaces at the end of strings:

• For PAD SPACE collations, trailing spaces are insignificant in comparisons; strings are compared without regard to trailing spaces.

• NO PAD collations treat trailing spaces as significant in comparisons, like any other character.

"Comparison" in this context does not include the LIKE pattern-matching operator, for which trailing spaces are significant, regardless of collation.

PAD SPACE:在排序和比较运算中,忽略字符串尾部空格。

NO PAD:在排序和比较运算中,字符串尾部空格当成普通字符,不能忽略。

3、问题解决

以下操作基于MySQL 8.0.25 社区版

3.1、查看字段使用的Collation

  1. mysql> show full fields in t1;
  2. +-------+------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
  3. | Field | Type | Collation | Null | Key | Default | Extra | Privileges | Comment |
  4. +-------+------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
  5. | c1 | int | NULL | YES | | NULL | | select,insert,update,references | |
  6. | c2 | varchar(4) | utf8mb4_unicode_ci | YES | | NULL | | select,insert,update,references | |
  7. +-------+------------+--------------------+------+-----+---------+-------+---------------------------------+---------+
  8. 2 rows in set (0.00 sec)

c2列的Collation是utf8mb4_unicode_ci。

3.2、查看Collation的Pad属性

  1. mysql> select COLLATION_NAME,PAD_ATTRIBUTE from INFORMATION_SCHEMA.COLLATIONS where COLLATION_NAME in('utf8mb4_unicode_ci','utf8mb4_0900_ai_ci');
  2. +--------------------+---------------+
  3. | COLLATION_NAME | PAD_ATTRIBUTE |
  4. +--------------------+---------------+
  5. | utf8mb4_0900_ai_ci | NO PAD |
  6. | utf8mb4_unicode_ci | PAD SPACE |
  7. +--------------------+---------------+
  8. 1 row in set (0.00 sec)

utf8mb4_unicode_ci的Pad属性是PAD SPACE,由2.3可知c2列在排序和比较运算中,忽略字符串尾部空格。

因此check比较时,会将插入的' '中的空格忽略,显然忽略空格后和check约束存在冲突,插入失败。

  1. mysql> SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci;
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> select ' ' = '';
  4. +--------+
  5. | ' '='' |
  6. +--------+
  7. | 1 |
  8. +--------+
  9. 1 row in set (0.00 sec)

3.3、如何让check约束按常规逻辑生效

这里的常规是指空格就是空格,不应该把空格忽略。只需将c2字段修改为NO PAD的Collation后,就能将空格正常插入:

  1. mysql> insert into t1 select 1,' '; #c2字段插入两个空格
  2. ERROR 3819 (HY000): Check constraint 't1_chk_1' is violated.
  3. mysql> alter table t1 modify c2 varchar(4) collate utf8mb4_0900_ai_ci; #修改为NO PAD的Collation
  4. Query OK, 0 rows affected (0.15 sec)
  5. Records: 0 Duplicates: 0 Warnings: 0
  6. mysql> insert into t1 select 1,' '; #c2字段插入两个空格
  7. Query OK, 1 row affected (0.12 sec)
  8. Records: 1 Duplicates: 0 Warnings: 0
  9. mysql> insert into t1 select 1,''; #''之间无空格
  10. ERROR 3819 (HY000): Check constraint 't1_chk_1' is violated.
  11. mysql> select c1,c2,hex(c2) from t1;
  12. +------+------+---------+
  13. | c1 | c2 | hex(c2) |
  14. +------+------+---------+
  15. | 1 | | 2020 |
  16. +------+------+---------+
  17. 1 row in set (0.01 sec)

4、扩展

4.1、如果c2列是CHAR类型,和前面的问题表现一样吗

一样。CHAR、VARCHAR、TEXT在做排序和比较运算时,都是依据列的Collation的Pad属性处理字符串尾部的空格。此时拿来做比较运算的字符串是insert中的内容。

4.2、WHERE条件中表现形式是怎样的

创建一张新表并插入数据

  1. mysql> create table t3(
  2. -> c1 int,
  3. -> c2 char(4) collate utf8mb4_unicode_ci,
  4. -> c3 char(4) collate utf8mb4_0900_ai_ci,
  5. -> c4 varchar(4) collate utf8mb4_unicode_ci,
  6. -> c5 varchar(4) collate utf8mb4_0900_ai_ci
  7. -> )engine=innodb;
  8. Query OK, 0 rows affected (0.29 sec)
  9. mysql> insert into t3 select 1,'a','a','a','a';
  10. Query OK, 1 row affected (0.09 sec)
  11. Records: 1 Duplicates: 0 Warnings: 0
  12. mysql> insert into t3 select 2,'a ','a ','a ','a '; #各列包含1个空格
  13. Query OK, 1 row affected (0.20 sec)
  14. Records: 1 Duplicates: 0 Warnings: 0
  15. mysql> insert into t3 select 3,'a ','a ','a ','a '; #前两列3个空格,后两列2个空格
  16. Query OK, 1 row affected (0.17 sec)
  17. Records: 1 Duplicates: 0 Warnings: 0
  18. mysql> insert into t3 select 4,'a ','a ','a ','a '; #前两列2个空格,后两列3个空格
  19. Query OK, 1 row affected (0.14 sec)
  20. Records: 1 Duplicates: 0 Warnings: 0

观察WHERE条件返回结果,CHAR类型的返回受PAD_CHAR_TO_FULL_LENGTH影响(参考2.1)

  1. mysql> set sql_mode='';
  2. Query OK, 0 rows affected (0.00 sec)
  3. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c2='a';
  4. +------+------+------+------+------+---------+---------+----------+----------+
  5. | c1 | c2 | c3 | c4 | c5 | hex(c2) | hex(c3) | hex(c4) | hex(c5) |
  6. +------+------+------+------+------+---------+---------+----------+----------+
  7. | 1 | a | a | a | a | 61 | 61 | 61 | 61 |
  8. | 2 | a | a | a | a | 61 | 61 | 6120 | 6120 |
  9. | 3 | a | a | a | a | 61 | 61 | 612020 | 612020 |
  10. | 4 | a | a | a | a | 61 | 61 | 61202020 | 61202020 |
  11. +------+------+------+------+------+---------+---------+----------+----------+
  12. 4 rows in set (0.00 sec)
  13. c2 char->返回数据去掉字符串尾部的空格
  14. c2 utf8mb4_unicode_ci->PAD SPACE->排序和比较运算,忽略字符串尾部空格
  15. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c3='a';
  16. +------+------+------+------+------+---------+---------+----------+----------+
  17. | c1 | c2 | c3 | c4 | c5 | hex(c2) | hex(c3) | hex(c4) | hex(c5) |
  18. +------+------+------+------+------+---------+---------+----------+----------+
  19. | 1 | a | a | a | a | 61 | 61 | 61 | 61 |
  20. | 2 | a | a | a | a | 61 | 61 | 6120 | 6120 |
  21. | 3 | a | a | a | a | 61 | 61 | 612020 | 612020 |
  22. | 4 | a | a | a | a | 61 | 61 | 61202020 | 61202020 |
  23. +------+------+------+------+------+---------+---------+----------+----------+
  24. 4 rows in set (0.01 sec)
  25. c3 char->返回数据去掉字符串尾部的空格
  26. c3 utf8mb4_0900_ai_ci->NO PAD->排序和比较运算,字符串尾部空格当成普通字符
  27. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c4='a';
  28. +------+------+------+------+------+---------+---------+----------+----------+
  29. | c1 | c2 | c3 | c4 | c5 | hex(c2) | hex(c3) | hex(c4) | hex(c5) |
  30. +------+------+------+------+------+---------+---------+----------+----------+
  31. | 1 | a | a | a | a | 61 | 61 | 61 | 61 |
  32. | 2 | a | a | a | a | 61 | 61 | 6120 | 6120 |
  33. | 3 | a | a | a | a | 61 | 61 | 612020 | 612020 |
  34. | 4 | a | a | a | a | 61 | 61 | 61202020 | 61202020 |
  35. +------+------+------+------+------+---------+---------+----------+----------+
  36. 4 rows in set (0.00 sec)
  37. c4 varchar->返回数据保留插入时的空格
  38. c4 utf8mb4_unicode_ci->PAD SPACE->排序和比较运算,忽略字符串尾部空格
  39. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c5='a';
  40. +------+------+------+------+------+---------+---------+---------+---------+
  41. | c1 | c2 | c3 | c4 | c5 | hex(c2) | hex(c3) | hex(c4) | hex(c5) |
  42. +------+------+------+------+------+---------+---------+---------+---------+
  43. | 1 | a | a | a | a | 61 | 61 | 61 | 61 |
  44. +------+------+------+------+------+---------+---------+---------+---------+
  45. 1 row in set (0.00 sec)
  46. c5 varchar->返回数据保留插入时的空格
  47. c5 utf8mb4_0900_ai_ci->NO PAD->排序和比较运算,字符串尾部空格当成普通字符
  48. mysql> set sql_mode='PAD_CHAR_TO_FULL_LENGTH';
  49. Query OK, 0 rows affected, 1 warning (0.01 sec)
  50. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c2='a';
  51. +------+------+------+------+------+----------+----------+----------+----------+
  52. | c1 | c2 | c3 | c4 | c5 | hex(c2) | hex(c3) | hex(c4) | hex(c5) |
  53. +------+------+------+------+------+----------+----------+----------+----------+
  54. | 1 | a | a | a | a | 61202020 | 61202020 | 61 | 61 |
  55. | 2 | a | a | a | a | 61202020 | 61202020 | 6120 | 6120 |
  56. | 3 | a | a | a | a | 61202020 | 61202020 | 612020 | 612020 |
  57. | 4 | a | a | a | a | 61202020 | 61202020 | 61202020 | 61202020 |
  58. +------+------+------+------+------+----------+----------+----------+----------+
  59. 4 rows in set (0.00 sec)
  60. c2 char->PAD_CHAR_TO_FULL_LENGTH->返回数据字符串右边补充空格
  61. c2 utf8mb4_unicode_ci->PAD SPACE->排序和比较运算,忽略字符串尾部空格
  62. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c3='a';
  63. Empty set (0.00 sec)
  64. c3 char->PAD_CHAR_TO_FULL_LENGTH->返回数据字符串右边补充空格
  65. c3 utf8mb4_0900_ai_ci->NO PAD->排序和比较运算,字符串尾部空格当成普通字符
  66. 1~4c3列返回值都包含空格,且c3列的CollationNO PAD,字符串尾部空格不能忽略,where过滤找不到记录
  67. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c4='a';
  68. +------+------+------+------+------+----------+----------+----------+----------+
  69. | c1 | c2 | c3 | c4 | c5 | hex(c2) | hex(c3) | hex(c4) | hex(c5) |
  70. +------+------+------+------+------+----------+----------+----------+----------+
  71. | 1 | a | a | a | a | 61202020 | 61202020 | 61 | 61 |
  72. | 2 | a | a | a | a | 61202020 | 61202020 | 6120 | 6120 |
  73. | 3 | a | a | a | a | 61202020 | 61202020 | 612020 | 612020 |
  74. | 4 | a | a | a | a | 61202020 | 61202020 | 61202020 | 61202020 |
  75. +------+------+------+------+------+----------+----------+----------+----------+
  76. 4 rows in set (0.00 sec)
  77. c4 varchar->返回数据保留插入时的空格
  78. c4 utf8mb4_unicode_ci->PAD SPACE->排序和比较运算,忽略字符串尾部空格
  79. mysql> select *,hex(c2),hex(c3),hex(c4),hex(c5) from t3 where c5='a';
  80. +------+------+------+------+------+----------+----------+---------+---------+
  81. | c1 | c2 | c3 | c4 | c5 | hex(c2) | hex(c3) | hex(c4) | hex(c5) |
  82. +------+------+------+------+------+----------+----------+---------+---------+
  83. | 1 | a | a | a | a | 61202020 | 61202020 | 61 | 61 |
  84. +------+------+------+------+------+----------+----------+---------+---------+
  85. 1 row in set (0.00 sec)
  86. c5 varchar->返回数据保留插入时的空格
  87. c5 utf8mb4_0900_ai_ci->NO PAD->排序和比较运算,字符串尾部空格当成普通字符

此时拿来做比较运算的字符串是Retrieved的内容,CHAR和VARCHAR返回数据时对字符串尾部的空格处理方式不同,并且PAD_CHAR_TO_FULL_LENGTH只影响CHAR类型。

4.3、对唯一索引的影响

https://dev.mysql.com/doc/refman/8.0/en/char.html

For those cases where trailing pad characters are stripped or comparisons ignore them, if a column has an index that requires unique values, inserting into the column values that differ only in number of trailing pad characters results in a duplicate-key error. For example, if a table contains 'a', an attempt to store 'a ' causes a duplicate-key error.

如果存在唯一索引(单列、字符类型),插入的数据仅在尾部空格个数不同,有可能会报duplicate-key错误:

  1. mysql> select c1,c4,c5,hex(c4),hex(c5) from t3;
  2. +------+------+------+----------+----------+
  3. | c1 | c4 | c5 | hex(c4) | hex(c5) |
  4. +------+------+------+----------+----------+
  5. | 1 | a | a | 61 | 61 |
  6. | 2 | a | a | 6120 | 6120 |
  7. | 3 | a | a | 612020 | 612020 |
  8. | 4 | a | a | 61202020 | 61202020 |
  9. +------+------+------+----------+----------+
  10. 4 rows in set (0.00 sec)
  11. mysql> alter table t3 add unique(c4);
  12. ERROR 1062 (23000): Duplicate entry 'a' for key 't3.c4'
  13. mysql> alter table t3 add unique(c5);
  14. Query OK, 0 rows affected (0.44 sec)
  15. Records: 0 Duplicates: 0 Warnings: 0

可以看到c4列创建唯一索引失败,c5列创建唯一索引成功。

c4 utf8mb4_unicode_ci->PAD SPACE->排序和比较运算,忽略字符串尾部空格,4行数据重复。

c5 utf8mb4_0900_ai_ci->NO PAD->排序和比较运算,字符串尾部空格当成普通字符,4行数据不同。

5、总结

Stored

- CHAR(N) VARCHAR(N)
Stored 字符不足N右边补空格 保留插入时的空格,不会在右边额外补充空格

Retrieved

SQL_MODE CHAR(N) VARCHAR(N)
Default Value 去掉字符串尾部的空格 保留插入时的空格
PAD_CHAR_TO_FULL_LENGTH 返回完整字符串,不足N右边补空格 保留插入时的空格

Comparison(不包括like)

| Pad Attribute | CHAR(N)/VARCHAR(N) |

| --- | --- |--- |

| PAD SPACE | 忽略字符串尾部空格 |

| NO PAD | 字符串尾部空格当成普通字符,不能忽略 |

Enjoy GreatSQL

文章推荐:

技术分享 | MGR最佳实践(MGR Best Practice)

https://mp.weixin.qq.com/s/66u5K7a9u8GcE2KPn4kCaA

技术分享 | 万里数据库MGR Bug修复之路

https://mp.weixin.qq.com/s/IavpeP93haOKVBt7eO8luQ

Macos系统编译percona及部分函数在Macos系统上运算差异

https://mp.weixin.qq.com/s/jAbwicbRc1nQ0f2cIa_2nQ

技术分享 | 利用systemd管理MySQL单机多实例

https://mp.weixin.qq.com/s/iJjXwd0z1a6isUJtuAAHtQ

产品 | GreatSQL,打造更好的MGR生态

https://mp.weixin.qq.com/s/ByAjPOwHIwEPFtwC5jA28Q

产品 | GreatSQL MGR优化参考

https://mp.weixin.qq.com/s/5mL_ERRIjpdOuONian8_Ow

关于 GreatSQL

GreatSQL是由万里数据库维护的MySQL分支,专注于提升MGR可靠性及性能,支持InnoDB并行查询特性,是适用于金融级应用的MySQL分支版本。

Gitee:

https://gitee.com/GreatSQL/GreatSQL

GitHub:

https://github.com/GreatSQL/GreatSQL

微信&QQ群:

可扫码添加GreatSQL社区助手微信好友,发送验证信息“加群”加入GreatSQL/MGR交流微信群,亦可直接扫码加入GreatSQL/MGR交流QQ群。

本文由博客一文多发平台 OpenWrite 发布!

技术分享 | check(col_name<>'')为何把空格拒之门外的更多相关文章

  1. 【转发】网易邮箱前端技术分享之javascript编码规范

    网易邮箱前端技术分享之javascript编码规范 发布日期:2013-11-26 10:06 来源:网易邮箱前端技术中心 作者:网易邮箱 点击:533 网易邮箱是国内最早使用ajax技术的邮箱.早在 ...

  2. UWP 手绘视频创作工具技术分享系列 - SVG 的解析和绘制

    本篇作为技术分享系列的第一篇,详细讲一下 SVG 的解析和绘制,这部分功能的研究和最终实现由团队的 @黄超超 同学负责,感谢提供技术文档和支持. 首先我们来看一下 SVG 的文件结构和组成 SVG ( ...

  3. AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享

    原文:AY写给国人的教程- VS2017 Live Unit Testing[1/2]-C#人爱学不学-aaronyang技术分享 谢谢大家观看-AY的 VS2017推广系列 Live Unit Te ...

  4. 【技术分享】小乖乖的 Linux/Ubuntu 历险记

    本文将同步发布于 WHU-TD 的博客. 这是一篇自带故事背景的博客. 总所周知,写的多,错的多,更何况一个刚刚接触 Linux 的小白.虽然只是介绍一些非常基础的内容,还是希望大家在发现错误时可以及 ...

  5. 技术分享PPT整理(一):Bootstrap基础与应用

    最近在复习的时候总感觉有些知识点总结过,但是翻了一下博客没有找到,才想起来有一些内容是放在部门的技术分享里的,趁这个时候跳了几篇相对有价值的梳理一下,因为都是PPT,所以内容相对零散,以要点和图片为主 ...

  6. 技术分享 | 测试git上2500星的闪回小工具

    GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. 1.实验环境 2.软件下载 3.开始测试 4.附参数说明 生产上发生误删数据或者误更新数据的事故时,传统恢复方法是利用备份 ...

  7. 技术分享 | 简单测试MySQL 8.0.26 vs GreatSQL 8.0.25的MGR稳定性表现

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 GreatSQL社区原创内容未经授权不得随意使用,转载请联系小编并注明来源. M ...

  8. 技术分享 | 在MySQL对于批量更新操作的一种优化方式

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 作者:景云丽.卢浩.宋源栋 GreatSQL社区原创内容未经授权不得随意使用,转 ...

  9. fir.im Weekly - 新开发时代,需要什么样的技术分享

    "2016年,当我们迎来了如Xcode 8.Swift 3.SiriKit.Android N.Android Instant Apps.React Native等诸多移动开发技术.开发工具 ...

随机推荐

  1. IntelliJ IDEA中如何优雅的调试Java Stream操作

    Stream操作是Java 8推出的一大亮点!虽然java.util.stream很强大,但依然还是有很多开发者在实际工作中很少使用,其中吐槽最多的一个原因就是不好调试,一开始确实是这样,因为stre ...

  2. python文件操作拓展与认识函数

    目录 文件内光标的移动(了解即可) 前言 控制光标移动seek()方法 文件的修改 函数 语法结构 简单的使用 作业 答案 文件内光标的移动(了解即可) 前言 在文件的内置方法中,read()方法是可 ...

  3. 第06组 Beta冲刺 (1/6)

    目录 1.1 基本情况 1.2 冲刺概况汇报 1.郝雷明 2. 方梓涵 3.曾丽莉 4.黄少丹 5. 董翔云 6.杜筱 7.鲍凌函 8.詹鑫冰 9.曹兰英 10.吴沅静 1.3 冲刺成果展示 1.1 ...

  4. SQL年龄计算方法

    第一种方法: 用DATEDIFF函数,DATEDIFF(YEAR,beginDate,endDate). 测试语句: 1 DECLARE @birthdayDate DATE 2 DECLARE @e ...

  5. 题解0014:信奥一本通1472——The XOR Largest Pair(字典树)

    题目链接:http://ybt.ssoier.cn:8088/problem_show.php?pid=1472 题目描述:在给定的 N 个整数中选出两个进行异或运算,求得到的结果最大是多少. 看到这 ...

  6. 开发工具-Java SDK下载地址

    更新记录 2022年6月14日 加入更多的下载地址. 2022年6月10日 完善标题. 下载地址: https://www.oracle.com/java/technologies/downloads ...

  7. Python双人五子棋

    这篇文章旨在介绍一个双人的五子棋程序.再次重申,本人不擅长对代码的可读性进行优化,所以可能有些杂乱(在所难免). 先瞅一眼效果图: 请注意,这个棋子--是这么圆润立体!本程序不需任何素材图片,完全用代 ...

  8. SQLite数据库损坏及其修复探究

    数据库如何发生损坏   SQLite 数据库具有很强的抗损坏能力.在执行事务时如果发生应用程序崩溃.操作系统崩溃甚至电源故障,那么在下次访问数据库文件时,会自动回滚部分写入的事务.恢复过程是全自动的, ...

  9. javaweb_Http学习

    1. 什么是HTTP? HTTP(超文本传输协议)是一个简单的请求-响应协议,它通常运行在TCP之上. 文本:html,字符串,~... 超文本:图片,音乐,视频,定位,地图..... 默认端口:80 ...

  10. 一分钟入门 Babel(下一代 JavaScript 语法的编译器)

    简单来说把 JavaScript 中 es2015/2016/2017/2046 的新语法转化为 es5,让低端运行环境(如浏览器和 node )能够认识并执行.严格来说,babel 也可以转化为更低 ...