数据类型由mysql内部定义。
如果直接写tinyint,bigint这样的,默认是有符号的,取值范围同C定义的那样。
创建一个数据库和简单的表。
插入几个值
这里就能够看出,tinyint范围是-128 - 127。再看一个无符号的
只要超出范围,mysql就不做插入操作,并返回错误。所以mysql的数据一定都是合法的。这也是一种对使用者的约束。而C的一些编译器,如果写了char a = 1234567,我们知道实际不是存的不是这个值,但这种做法是错误的,编译器也不报错,而是默默存了进去,并警告一下。数据库的这种做法能保证数据是可预期的,完整的。
创建时就指定了bit只有1个位置,也就是只有1个bit位,只能表示1和0,所以插入4就错误。不过即使插入成功,用desc命令也看不到,因为这个是位结构,显示时会以ASCII码值的形式来显示,只是此时这里默认设置的是不可见的ASCII码值。 想看到的话
select hex(列名) from 表名;
可以插入一个’a’,在ASCII码表里的字符,那么就能直接显示出来。
bit最多的位数是64,插入时以二进制形式插入,显示时以ASCII码值形式显示。
float(m, d),m是显示长度,d是小数位数。比如float(4, 2)的范围是-99.99 ~ 99.99。
超出范围报错,不符合要求的也报错,报错时都不插入数据。范围内的会自动添加0来符合d和m的要求,如果本身就符合那就不添加;如果在范围内但不符合要求,比如23.456,那就存入23.46,采用四舍五入的方式来存入;但99.993这样的,存入的都是99.99;如果是99.995,四舍五入就超过范围了,所以直接报错;插入0会变成0.00。
如果用float无符号的,那么desc 表名后就能看到float后有个unsigned。但此时插入99.996这样的还是不行,说明上限没有变;任何负数都不能插入,不管是否是四舍五入。所以无符号的相对于有符号的就是把负数部分直接去掉;无符号也遵守四舍五入。
创建时float后不写括号,用mysql默认的float,desc查看表时也是float后不显示什么,这时候存入的数可以很大,由mysql决定。默认的精度是2位小数,如果小数点左面的数过大,那就只保留最左边6个数字,剩下的变为0,然后去掉小数点之后的数字。
同float一样,也有m和d,意义相同;decimal也遵守四舍五入;float会有精度损失,decimal更好些。比如都是小数点后位数多的数字,float即使符合自己的要求,但存入的数字可能会和原数字不一样,因为float会自己做点调整,而decimal则传什么存什么。
decimal的m最大为65,d最大为30,m和d默认是10和0。如果要求小数的精度大,则用decimal。
char类型是固定长度字符串,后面的括号内就是可以存储的长度,单位是字符,最大长度值是255。
超过长度就报错。像上图,中文字符也可以插入2个,虽然utf8规定中1个中文字符占3个字节。mysql中的字符和C中的字符不一样,mysql中的字符就代表一个符号,不论这个符号占据多少个字节。
char最多为255,超过就报错,并建议用户用其它的类型。
varchar是变长字符串,后面括号内填的是字符长度,最大长度为65535个字节,也就是21845个字符,但有1-3个字节记录数据大小,所以有效字节数是65532,也就是21844个字符,这是utf8的规则。gbk则是32766个字符,一个字符占两个字节。
第一个逗号有空格,所以总体是7个字符,就超过了。
varchar和char的区别在于,char定义时是多少个字符,那么就开多少空间;varchar则是用多少开多少,即使varchar(6),但只存了一个字符,那也就只提供一个字符的空间。不过上限还是有,这不影响什么。
varchar括号内的数值包含了定义的其它列,所以如果还有别的列,那么最大就是21844,还需要减小点。
比较一下char和varchar
如果数据确定长度都一样,就使用定长(char),比如:身份证,手机号,密码
如果数据长度有变化,就使用变长(varchar),比如:名字,地址,但要保证最长的能存的进去。
定长的磁盘空间比较浪费,但是效率高。
变长的磁盘空间比较节省,但是效率低。
定长的意义是,直接开辟好对应的空间
变长的意义是,在不超过自定义范围的情况下,用多少,开辟多少。
date:日期’yyyy-mm-dd’ ,只需要日期而不需要时间时用,占用三字节
datetime:时间日期格式’yyyy-mm-dd HH:ii:s’,表示范围从1000到9999,允许用户传入时间,占用八字节
timestamp:时间戳,从1970年开始的 yyyy-mm-dd HH:ii:ss 格式和 datetime 完全一致,占用四字节
当对timestamp进行增加或更改时,Extra处会自动变成当前系统时间。其它两个通过mysql语句来更改。
enum是枚举类型,set是集合类型。
枚举类型可以用下标来访问,从1开始。可以插入多个集合中的元素
insert into votes values ('乙', 2, '足球,计算机,排球');
不过几个之间没有空格,有空格的话那么集合的元素也得带上空格。
enum和set在插入时可以为空,也就是insert时不写这两个,那就插入NULL;set处也可以插入数字,从1开始,如果是0,那么select一下就会看到那块地方什么都没有,插入的是空串而不是NULL。假设set有4个元素,就是4个比特位,插入哪个数字就是把这几个比特位表示成这个数字,哪个位置是1就插入哪个,也会插入多个元素。
enum每一个元素是下标,set每一个元素是位图。
筛选
select * from 表名 where 列名=元素(或数字);
但是这样的筛选会选择只符合这个条件的,如果是像上面那样一个人物有多个爱好,筛选其中一个爱好,就不会选择上这些多爱好的人。所以这种方法是严格筛选的。
用mysql的筛选函数
select find_in_set(‘a’, ‘a,b,c’)
查找a是否在abc中,找到返回下标,从1开始,不在或者查多个元素时就返回0,所以这个函数不能查找多个元素。
要查找多个元素,在上面find_in_set函数后加上
空格 and find_in_set();
结束。