zoukankan      html  css  js  c++  java
  • 一次故障解决过程梳理:mysql varchar text timestamp

    CHAR 类型的一个变体是 VARCHAR 类型,char(M),M是指字节长度,和varchar(M)一样

    故障原因:
    mysql主键设置为int(9),但数据量已经大于int(9)的范围了 
    tips:int最大长度是11. 如果在建表时不指定字段int类型的长度时,系统则默认生成长度为11的字段。

    解决过程中的坑:
    因为更改字段类型太慢(亿级数据量),就新建了个相同结构的表,然后更改代码中的sql准备把应用启动起来。

    问题1:因为shell脚本是在notepad++中修改的,修改后没有保存,导致一直没有生效-------更改了什么东西一些要确认更新才行
    问题2:使用一个权限比较低的用户上传到Linux后,项目文件也在这个用户下,导致cd一个目录时没有权限  ----使用chown更改权限后,居然还cd不进去,这种情况不应该发生,但对这个代码不熟,原因不确定
    问题3:接口返回的数据有异常,但日志并没有报错。原因:try catch之后,catch中没有打印Exception stace,而是在catch中直接赋了一个默认值

    CREATE TABLE t_role(
    id INT(11) NOT NULL AUTO_INCREMENT,
    role_name VARCHAR(60) NOT NULL,
    create_date DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,
    note VARCHAR(512) DEFAULT NULL,
    PRIMARY KEY(id)
    );
    INSERT INTO t_role(role_name)VALUES('100');


    临时解决办法是将Mysql 主键的字段类型更改为bigint(22).

    digest:

    The "BIGINT(20)" specification isn't a digit limit. It just means  that when the data is displayed, if it uses less than 20 digits it will be  left-padded with zeros. 
    2^64 is the hard limit for the BIGINT type, and has 20 digits itself, hence BIGINT(20) just means everything less than 10^20 will beleft-padded with spaces on display
    This is kind of getting off topic though, so... 

    Here's the full column definition:`term_id` bigint(20) NOT NULL auto_increment

    The '20' is the maximum display width
    However, this does NOT limit  the range of values that can be stored in this column, which for bigint is: -9223372036854775808 to 9223372036854775807

    If its unsigned (which this one is not), a bigint has this range: 0 to 18446744073709551615

    If you specify zerofill as one of the options in the column definition, values will be left-padded with zeros. Displaying the value without zerofill will left-pad with spaces.

    More info here:
    http://dev.mysql.com/doc/refman/5.0/en/numeric-type-overview.html
    http://dev.mysql.com/doc/refman/5.0/en/numeric-types.html

    http://lists.automattic.com/pipermail/wp-hackers/2008-March/018522.html

    See http://dev.mysql.com/doc/refman/5.1/en/numeric-types.html

    INT is a four-byte signed integer. BIGINT is an eight-byte signed integer.

    The 20 in INT(20) and BIGINT(20) means almost nothing. It's a hint for display width, it has nothing to do with storage. Practically, it affects only the ZEROFILL option:

    CREATE TABLE foo ( bar INT(20) ZEROFILL );
    INSERT INTO foo (bar) VALUES (1234);
    SELECT bar from foo;
    
    +----------------------+
    | bar                  |
    +----------------------+
    | 00000000000000001234 |
    +----------------------+

     It's a common source of confusion for MySQL users to see INT(20) and assume it's a size limit, something analogous to CHAR(20).

    http://stackoverflow.com/questions/3135804/types-in-mysql-bigint20-vs-int20


    譬如下例中,BIGINT(255)实际上存放数值的最大长度是19。因此,BIGINT(20)是建议的写法

    DROP TABLE if EXISTS `testM`;
    CREATE TABLE `testM` (
    id BIGINT(255) not null AUTO_INCREMENT,
    `ab` varchar(500) DEFAULT NULL,
    PRIMARY key (id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    
    DELETE from testM;
    SELECT * from testM;
    
    INSERT into testM (id,ab)VALUES(123456789123456789123,'123456789123456789123');
    
    select LENGTH(id),LENGTH(ab),id,ab from testM;

    CREATE TABLE foo ( bar INT(20) ZEROFILL );
    INSERT INTO foo (bar) VALUES (1234);
    SELECT bar from foo;
    
    +----------------------+
    | bar                  |
    +----------------------+
    | 00000000000000001234 |
    +----------------------+

    http://stackoverflow.com/questions/2023481/mysql-large-varchar-vs-text

    Tips:

    11.2.1 Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT

    MySQL supports the SQL standard integer types INTEGER (or INT) and SMALLINT. As an extension to the standard, MySQL also supports the integer types TINYINTMEDIUMINT, and BIGINT. The following table shows the required storage and range for each integer type. 

    https://dev.mysql.com/doc/refman/5.5/en/integer-types.html

    M indicates the maximum display width for integer types. The maximum display width is 255. Display width is unrelated to the range of values a type can contain, as described in Section 11.2, “Numeric Types”. For floating-point and fixed-point types, M is the total number of digits that can be stored.
    If you specify ZEROFILL for a numeric column, MySQL automatically adds the UNSIGNED attribute to the column.
    Numeric data types that permit the UNSIGNED attribute also permit SIGNED. However, these data types are signed by default, so the SIGNED attribute has no effect.

    SERIAL is an alias for BIGINT UNSIGNED NOT NULL AUTO_INCREMENT UNIQUE.
    SERIAL DEFAULT VALUE in the definition of an integer column is an alias for NOT NULL AUTO_INCREMENT UNIQUE.

    Warning
    When you use subtraction between integer values where one is of type UNSIGNED, the result is unsigned unless the NO_UNSIGNED_SUBTRACTION SQL mode is enabled. See Section 12.10, “Cast Functions and Operators”.

    BIT[(M)]
    A bit-value type. M indicates the number of bits per value, from 1 to 64. The default is 1 if M is omitted.

    TINYINT[(M)] [UNSIGNED] [ZEROFILL]
    A very small integer. The signed range is -128 to 127. The unsigned range is 0 to 255.

    CREATE TABLE `testSERIAL` (
    id SERIAL,
    `ab` varchar(500) DEFAULT NULL,
    PRIMARY key (id)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    实际的DDL:

    CREATE TABLE `testSERIAL` (
      `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
      `ab` varchar(500) DEFAULT NULL,
      PRIMARY KEY (`id`),
      UNIQUE KEY `id` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    BOOL, BOOLEAN
    These types are synonyms for TINYINT(1). A value of zero is considered false. Nonzero values are considered true:

    mysql> SELECT IF(0, 'true', 'false');
    +------------------------+
    | IF(0, 'true', 'false') |
    +------------------------+
    | false                  |
    +------------------------+
    
    mysql> SELECT IF(1, 'true', 'false');
    +------------------------+
    | IF(1, 'true', 'false') |
    +------------------------+
    | true                   |
    +------------------------+
    
    mysql> SELECT IF(2, 'true', 'false');
    +------------------------+
    | IF(2, 'true', 'false') |
    +------------------------+
    | true                   |
    +------------------------+

    However, the values TRUE and FALSE are merely aliases for 1 and 0, respectively, as shown here:

    mysql> SELECT IF(0 = FALSE, 'true', 'false');
    +--------------------------------+
    | IF(0 = FALSE, 'true', 'false') |
    +--------------------------------+
    | true                           |
    +--------------------------------+
    
    mysql> SELECT IF(1 = TRUE, 'true', 'false');
    +-------------------------------+
    | IF(1 = TRUE, 'true', 'false') |
    +-------------------------------+
    | true                          |
    +-------------------------------+
    
    mysql> SELECT IF(2 = TRUE, 'true', 'false');
    +-------------------------------+
    | IF(2 = TRUE, 'true', 'false') |
    +-------------------------------+
    | false                         |
    +-------------------------------+
    
    mysql> SELECT IF(2 = FALSE, 'true', 'false');
    +--------------------------------+
    | IF(2 = FALSE, 'true', 'false') |
    +--------------------------------+
    | false                          |
    +--------------------------------+

    The last two statements display the results shown because 2 is equal to neither 1 nor 0.

    https://dev.mysql.com/doc/refman/5.5/en/numeric-type-overview.html


    unsinged可以增加数据长度。但也有问题就是id相减时,如果用负就会报错或溢出
    unsigned关键字只能用于整数,不能应用于浮点型和字符型
    binary只能应用于varchar,char,不能应用于整数和浮点型

    把整数类型设置unsigned示例

    mysql> CREATE TABLE t ( a INT UNSIGNED, b INT UNSIGNED )
    ENGINE=INNODB;
    Query OK, 0 rows affected (0.06 sec)
    mysql> INSERT INTO t SELECT 1,2;
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0
    mysql> SELECT * FROM tG;
    *************************** 1. row ***************************
    a: 1
    b: 2

    id相关为负时出现的异常,视os不同,现象也略有不同:

    mysql> SELECT a -b FROM tG;
    *************************** 1. row ***************************
    a - b: 4294967295
    1 row in set (0.00 sec)
    mysql> SELECT a-b FROM t;
    ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(`test`.`t`.`a` - `test`.`t`.`b`)'

    MySQL数据类型:UNSIGNED注意事项

    1. UNSIGNED
    UNSIGNED属性就是将数字类型无符号化,与C、C++这些程序语言中的unsigned含义相同。例如,INT的类型范围是-2 147 483 648 ~ 2 147 483 647, INT UNSIGNED的范围类型就是0 ~ 4 294 967 295。
    在MYSQL中整型范围:

    类型 大小 范围(有符号) 范围(无符号) 用途
    TINYINT 1 字节 (-128,127) (0,255) 小整数值
    SMALLINT 2 字节 (-32 768,32 767) (0,65 535) 大整数值
    MEDIUMINT 3 字节 (-8 388 608,8 388 607) (0,16 777 215) 大整数值
    INT或INTEGER 4 字节 (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
    源文档 <http://www.cnblogs.com/bukudekong/archive/2011/06/27/2091590.html>

    看起来这是一个不错的属性选项,特别是对于主键是自增长的类型,因为一般来说,用户都希望主键是非负数。然而在实际使用中,UNSIGNED可能会带来一些负面的影响,示例如下:
    mysql> CREATE TABLE t ( a INT UNSIGNED, b INT UNSIGNED )
    ENGINE=INNODB;
    Query OK, 0 rows affected (0.06 sec)
    mysql> INSERT INTO t SELECT 1,2;
    Query OK, 1 row affected (0.00 sec)
    Records: 1 Duplicates: 0 Warnings: 0
    mysql> SELECT * FROM tG;
    *************************** 1. row ***************************
    a: 1
    b: 2
    1 row in set (0.00 sec)
    我们创建了一个表t,存储引擎为InnoDB。表t上有两个UNSIGNED的INT类型。输入(1,2)这一行数据,目前看来都没有问题,接着运行如下语句:
    SELECT a - b FROM t
    这时结果会是什么呢?会是-1吗?答案是不确定的,可以是-1,也可以是一个很大的正值,还可能会报错。在Mac操作系统中(windows中也会),MySQL数据库提示如下错误:
    mysql> SELECT a-b FROM t;
    ERROR 1690 (22003): BIGINT UNSIGNED value is out of range in '(`test`.`t`.`a` - `test`.`t`.`b`)'
    这个错误乍看起来非常奇怪,提示BIGINT UNSIGNED超出了范围,但是我们采用的类型都是INT UNSIGNED啊!而在另一台Linux操作系统中,运行的结果却是:

    mysql> SELECT a -b FROM tG;
    *************************** 1. row ***************************
    a - b: 4294967295
    1 row in set (0.00 sec)

    在发生上述这个问题的时候,有开发人员跑来和笔者说,他发现了一个MySQL的Bug,MySQL怎么会这么“傻”呢?在听完他的叙述之后,我写了如下的代码并告诉他,这不是MySQL的Bug,C语言同样也会这么“傻”。
    #include
    int main(){
    unsigned int a;
    unsigned int b;
    a = 1;
    b = 2;
    printf(a - b: %d ,a-b);
    printf(a - b: %u ,a-b);
    return 1;
    }

    上述代码的运行结果是:
    a - b: -1
    a - b: 4294967295
    可以看到,在C语言中a-b也可以返回一个非常巨大的整型数,这个值是INT UNSIGNED的最大值。难道C语言也发生了Bug?这怎么可能呢?
    在实际的使用过程中,MySQL给开发人员的印象就是存在很多Bug,只要结果出乎预料或者有开发人员不能理解的情况发生时,他们往往把这归咎于MySQL的 Bug。和其他数据库一样,MySQL的确存在一些Bug,其实并不是MySQL数据库的Bug比较多,去看一下Oracle RAC的Bug,那可能就更多了,它可是Oracle的一款旗舰产品。因此,不能简单地认为这个问题是MySQL的Bug。
    对于上述这个问题,正如上述所分析的,如果理解整型数在数据库中的表示方法,那么这些就非常好理解了,这也是为什么之前强调需要看一些计算机组成原理方面相关书籍的原因。将上面的C程序做一些修改:
    #include
    int main(){
    unsigned int a;
    unsigned int b;
    a = 1;
    b = 2;
    printf(a - b: %d,%x ,a-b,a-b);
    printf(a - b: %u,%x ,a-b,a-b);
    return 1;
    }
    这次不仅打印出a-b的结果,也打印出a-b的十六进制结果,运行程序后的结果如下所示:
    a - b: -1,ffffffff
    a - b: 4294967295,ffffffff
    可以看到结果都是0xFFFFFFFF,只是0xFFFFFFFF可以代表两种值:对于无符号的整型值,其是整型数的最大值,即4 294 967 295;对于有符号的整型数来说,第一位代表符号位,如果是1,表示是负数,这时应该是取反加1得到负数值,即-1。

    这个问题的核心是,在MySQL数据库中,对于UNSIGNED数的操作,其返回值都是UNSIGNED的。而正负数这个问题在《MySQL技术内幕:InnoDB存储引擎》中有更深入的分析,有兴趣的可以进一步研究。
    那么,怎么获得-1这个值呢?这并不是一件难事,只要对SQL_MODE这个参数进行设置即可,例如:
    mysql>SET sql_mode='NO_UNSIGNED_SUBTRACTION';
    Query OK, 0 rows affected (0.00 sec)
    mysql> SELECT a-b FROM tG;
    *************************** 1. row ***************************
    a-b: -1
    1 row in set (0.00 sec)
    后面会对SQL_MODE进一步讨论,这里不进行深入的讨论。笔者个人的看法是尽量不要使用UNSIGNED,因为可能会带来一些意想不到的效果。另外,对于INT类型可能存放不了的数据,INT UNSIGNED同样可能存放不了,与其如此,还不如在数据库设计阶段将INT类型提升为BIGINT类型。

    以上文字摘自<http://tech.it168.com/a2012/0808/1382/000001382732.shtml>
    本人遇到的类似问题:(linux上)
    当(a-b)在where子句后时也会出现相同的情况
    以下是php使用Mysql查询的结果(每组的第一行是第二行[1]-[2]的结果)
    86374
    a
    Array ( [1] => 1351843032 [2] => 1351756658 )
    -2567
    Array ( [1] => 1351843032 [2] => 1351845599 )
    86374
    Array ([1] => 1351843032 [2] => 1351756658 )
    86374
    Array ( [1] => 1351843032 [2] => 1351756658 )
    -105849
    Array ( [1] => 1351650809 [2] => 1351756658 )
    86374
    Array ( [1] => 1351843032 [2] => 1351756658 )
    86374
    Array ( [1] => 1351843032 [2] => 1351756658 )

    下面在mysql语句中查询select * from table where (a-b)>86374;

    结果(按正常思路来讲,结果应该为空,但在Linux是却现出以下结果 ):

    Array ( [1] => 1351843032 [2] => 1351845599 )

    Array ( [1] => 1351650809 [2] => 1351756658 )

    而这个结果恰是[1]-[2]为负数的那两行。

    结论:如果使用unsigne并且在where子句后出现两列相减值小于0((a-b)<0),在查询时,linux上的Mysql会将负数转换成unsigned后再进行查询( (-2576+4294967295+1)>86374, (-105849+4294967295+1)>86374 )。

    http://www.cnblogs.com/blankqdb/archive/2012/11/03/blank_qdb.html

    mysql中varchar相关问题小结:
    varchar(M),这个M的单位是bytes,而不是字符个数
    mysql中的length(str):Returns the length of the string str, measured in bytes
    CHAR_LENGTH(str):Returns the length of the string str, measured in characters. A multibyte character counts as a single character. This means that for a string containing five 2-byte characters, LENGTH() returns 10, whereas CHAR_LENGTH() returns 5.

    timestamp类型的数据设置默认值:

    In version 5.6.5, it is possible to set a default value on a datetime column, and even make a column that will update when the row is updated. The type definition:

    CREATE TABLE foo (
        `creation_time`     DATETIME DEFAULT CURRENT_TIMESTAMP,
        `modification_time` DATETIME ON UPDATE CURRENT_TIMESTAMP
    )

    Reference: http://optimize-this.blogspot.com/2012/04/datetime-default-now-finally-available.html

    Previous versions can't do that with DATETIME,since MySQL 5.6.5----5.6.5之前的版本不能使用DATETIME,譬如下面的语句就不能正常执行:

    create table test (str varchar(32), ts DATETIME DEFAULT CURRENT_TIMESTAMP);

    But you can do it with TIMESTAMP:

    mysql> create table test (str varchar(32), ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP);
    Query OK, 0 rows affected (0.00 sec)
    
    mysql> desc test;
    +-------+-------------+------+-----+-------------------+-------+
    | Field | Type        | Null | Key | Default           | Extra |
    +-------+-------------+------+-----+-------------------+-------+
    | str   | varchar(32) | YES  |     | NULL              |       | 
    | ts    | timestamp   | NO   |     | CURRENT_TIMESTAMP |       | 
    +-------+-------------+------+-----+-------------------+-------+
    2 rows in set (0.00 sec)
    
    mysql> insert into test (str) values ("demo");
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from test;
    +------+---------------------+
    | str  | ts                  |
    +------+---------------------+
    | demo | 2008-10-03 22:59:52 | 
    +------+---------------------+
    1 row in set (0.00 sec)
    
    mysql>

     http://stackoverflow.com/questions/168736/how-do-you-set-a-default-value-for-a-mysql-datetime-column

    The DATE, DATETIME, and TIMESTAMP types are related. This section describes their characteristics, how they are similar, and how they differ. MySQL recognizes DATE, DATETIME, and TIMESTAMP values in several formats, described in Section 10.1.3, “Date and Time Literals”. For the DATE and DATETIME range descriptions, “supported” means that although earlier values might work, there is no guarantee.

    The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.

    The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'.

    The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of '1970-01-01 00:00:01' UTC to '2038-01-19 03:14:07' UTC.

    A DATETIME or TIMESTAMP value can include a trailing fractional seconds part in up to microseconds (6 digits) precision. In particular, any fractional part in a value inserted into a DATETIME or TIMESTAMP column is stored rather than discarded. With the fractional part included, the format for these values is 'YYYY-MM-DD HH:MM:SS[.fraction]', the range for DATETIME values is '1000-01-01 00:00:00.000000' to '9999-12-31 23:59:59.999999', and the range for TIMESTAMP values is '1970-01-01 00:00:01.000000' to '2038-01-19 03:14:07.999999'. The fractional part should always be separated from the rest of the time by a decimal point; no other fractional seconds delimiter is recognized. For information about fractional seconds support in MySQL, see Section 12.3.6, “Fractional Seconds in Time Values”.

    https://dev.mysql.com/doc/refman/5.7/en/datetime.html

    首先 DATETIME和TIMESTAMP类型所占的存储空间不同,前者8个字节,后者4个字节,这样造成的后果是两者能表示的时间范围不同。
    前者范围为1000-01-01 00:00:00 ~ 9999-12-31 23:59:59,后者范围为1970-01-01 08:00:01到2038-01-19 11:14:07。所以可以看到TIMESTAMP支持的范围比DATATIME要小,容易出现超出的情况.

    其次,TIMESTAMP类型在默认情况下,insert、update 数据时,TIMESTAMP列会自动以当前时间(CURRENT_TIMESTAMP)填充/更新。

    第三,TIMESTAMP比较受时区timezone的影响以及MYSQL版本和服务器的SQL MODE的影响

    所以一般来说,我比较倾向选择DATETIME,至于你说到索引的问题,选择DATETIME作为索引,如果碰到大量数据查询慢的情况,也可以分区表解决。
    https://segmentfault.com/q/1010000000121702


    varchar相关的一些示例:
    mysql版本:5.5.49-log

    DROP TABLE IF EXISTS testVarchar;
    CREATE TABLE testVarchar(
    id SERIAL,
    title VARCHAR(255),
    memo VARCHAR(20000),
    comments VARCHAR(65535),
    created_time TIMESTAMP not null DEFAULT CURRENT_TIMESTAMP
    );
    
    SELECT LENGTH(title),char_length(title),LENGTH(comments),char_length(comments),id,title,comments,created_time from testVarchar;
    
    INSERT into testVarchar(title,comments)VALUES(
    'Title 内容超过255部分的会被丢弃5.5.49-log。CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。',
    'CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。');
    
    INSERT into testVarchar(title,comments)VALUES(
    '刚好255内容CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。',
    'CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。');
    
    INSERT into testVarchar(title,comments)VALUES(
    'TitleCHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。',
    'CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。');
    INSERT into testVarchar(title,comments)VALUES(
    'CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。',
    'CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。');
    
    INSERT into testVarchar(title,comments)VALUES('Title 内容','CHAR 类型');
    INSERT into testVarchar(title,comments)VALUES('Title内容','CHAR类型');
    INSERT into testVarchar(title,comments)VALUES('Titl内容','CHA类型');
    INSERT into testVarchar(title,comments)VALUES('Titl容','CHA型');
    
    
    SELECT * from testVarchar where comments like '%型%';

    length: 是计算字段的长度一个汉字是算三个字符,一个数字或字母算一个字符
    char_length:不管汉字还是数字或者是字母都算是一个字符

    char会造成空间浪费,但是有速度优势;而varchar节省了空间,但是速度就不如char。

    经常变化的字段用varchar
    知道固定长度的用char
    尽量用varchar
    超过255字节的只能用varchar或者text
    能用varchar的地方不用text
    http://blog.csdn.net/ww122081351/article/details/18221013

    简单总结下下面的doc文档:如果varchar中存储的数据大于255 bytes是一种存储方式(1-byte length prefix plus data),如果大于255bytes是另一种和text相同的存储方式(2-byte length prefix plus data)

    The CHAR and VARCHAR types are similar, but differ in the way they are stored and retrieved. They also differ in maximum length and in whether trailing spaces are retained.
    The CHAR and VARCHAR types are declared with a length that indicates the maximum number of characters you want to store. For example, CHAR(30) can hold up to 30 characters.
    The length of a CHAR column is fixed to the length that you declare when you create the table. The length can be any value from 0 to 255. 
    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.
    Values in VARCHAR columns are variable-length strings. The length can be specified as a value from 0 to 65,535. 
    The effective maximum length of a VARCHAR is subject to the maximum row size (65,535 bytes, which is shared among all columns) and the character set used. 
    See Section C.10.4, “Limits on Table Column Count and Row Size”.
    In contrast to CHAR, VARCHAR values are stored as a 1-byte or 2-byte length prefix plus data. The length prefix indicates the number of bytes in the value. 
    A column uses one length byte if values require no more than 255 bytes, two length bytes if values may require more than 255 bytes.
    https://dev.mysql.com/doc/refman/5.7/en/char.html

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

    https://dev.mysql.com/doc/refman/5.7/en/string-functions.html

  • 相关阅读:
    QT 信号槽 异步事件驱动 单线程 多并发
    Qt 静态库与共享库(动态库)共享配置的一个小办法
    关于:有符号与无符号整数的大小比较
    QT信号槽 中的对象野指针
    Qt程序打包发布
    Qt程序打包发布
    SQL Server 2012 sa 用户登录 18456 错误 (转)
    QtCreator常用之快捷键
    opengl中相关的计算机图形变换矩阵之:模型视图几何变换
    opengl中相关的计算机图形变换矩阵之:齐次坐标 (摘编)
  • 原文地址:https://www.cnblogs.com/softidea/p/6681198.html
Copyright © 2011-2022 走看看