手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表Tag:database

精通MYSQL数据库——连载七

今天我们继续学习一下MYSQL的数据类型
浮点型
从MYSQL3.23开始,FLOAT和DOUBLE类型就一直分别对应着IEEE标准所定义的单精度浮点数和双精度浮点数,绝大多数编程语言也都支持这两种数据类型。
当某个字段设置成这两种类型时,会要求按(m,d)这样的格式输入参数,其中m和上文介绍INT时所讲的m效果一样,仅仅在显示/打印结果时有一定的排版作用,而对数据的精确度没有影响。可是d这个参数就不一样了,d代表了小数点后面的数字个数,而且会按照d的大小来进行四舍五入,例如:1234.5678如果存储到FLOAT(8,3)这样的字段里,实际存放的是1234.568,最后一位会四舍五入。
存储FLOAT和DOUBLE时,如果超出了这两种类型的范围,将会被替换成该类型的最大可取值(一般由当前操作系统决定,我不知道MYSQL是怎么样。),可以使用SHOW WARNING来查看警告内容。
MYSQL对浮点数有一定的要求,即一定要符合通用计数法,小数点一定是“.”,而不能是“,”(因为有部分欧洲国家使用逗号作为小数点,我也是第一次听说,黑黑),MYSQL永远会以这种写法向客户返回查询结果,只有在非常大或非常小的数值,会采用科学计数法表示,如1.234E+017。如果想让浮点数表现形式变成其他样式,有两种方式:一是利用SQL查询中的FORMAT函数,二是用客户端程序中的FORMAT函数,例如php中就可以使用sprintf或者number_format等来改变显示效果

类型 含义
FLOAT(m,d) 单精度浮点数,8位精度,占4字节
DOUBLE(m,d) 双精度浮点数,16位精度,占8字节
REAL(m,d) DOUBLE的同义词



说到浮点数,当然要提定点数
正因为MYSQL在处理浮点数时,最后一位会被自动的四舍五入,而我们实际上并不需要这一位被四舍五入(比如在处理财务数据时),怎么办呢?定点数可以解决这个问题。
定点数(DECIMAL)数字是以字符串的形式来进行存储的,并且不被允许存储指数形式,每位数字占用一个字节,外加两个字节的开销,所以,占用了更多的空间,但可表示的数值范围却比较小。
在进行存储的时候,也有两个参数DECIMAL(p,s)这回,这两个参数都有作用了。p代表了数据的总位数(不含小数点),最大65,s代表了小数点后的数字位数,最大为30。比方说:DECIMAL(6,3)取值范围为-999.999~999.999,这是新的版本的表示方法。不知道我有没有记错,我记得在以前的版本里,DECIMAL(6,3),这个6并不是代表了总位数,而是小数点前的位数(可能是在4.0吧)。
在MYSQL内部,定点数是被保存为二进制格式的,把定点数从小数点开始分割,并为它们各自分配所占用的字节数(最初是以每4个字节进行划分,虽然每个字节可以容纳2位数字,但4个字节却可以容纳9位数字,超过4个字节后,如果有多出的数字就划分一个字节来进行存储,同样如果是9位数字,还是只占4个字节)。根据这个规定,我们可以认为DECIMAL(6,3)其实是和DECIMAL(18,9)占用了同样多的字节数(8个字节)。如此说来DECIMAL(19,9)实际就占用了9个字节。

类型 含义
DECIMAL(p,s) 定点数,以字符串形式保存,最长为65
NUMERIC,DEC 同上(应该没有记错吧)

参考:http://dev.mysql.com/doc/refman/5.0/en/storage-requirements.html

Tags: database, mysql, 连载

精通MYSQL数据库——连载六

介绍完表的结构和存放位置后,下面的内容就是介绍MYSQL的数据类型了,毕竟为你想要的数据选定一个合适的类型,对于数据库的存取效率有很大的改进。
MYSQL数据库有以下几种类型:整数型(int,binint,smallint,tinyint等等xxxint型)、浮点型(float,double,real等)、定点数型(decimal,也就是传说中的浮点型的字符串表达形式)、日期与时间型(data,time,datetime,timestamp),字符串型(char,varchar,text,tinytext,mediumtext,longtext等),二进制型(tinyblob,tinyblob,blob等blob型),枚举型(enum,set——set是类似于enum型)。

下面从整数型开始详细介绍这些数型的基本信息:
整数型
默认情况下,INT类型既包括正数,也包括负数,如果给INT列定义UNSIGNED属性,那么它的取值范围就永远是正数。这个永远是正数,非常重要,即,如果你在对数据列操作:update tablename set int_field = (int_field - 1000 ),如果int_field的值小于1000,理论上是变成了负数,但由于你设的属性是UNSIGNED,那么存储的数据仍然是无符号的正数,这可能会给你带来虚假或让人困惑的结果。
TINYINT的取值范围是从-128~+127,如果使用了UNSIGNED属性,那么它的取值范围就变成了0~+255。如果用户试图存入超过字段取值范围的数字,MYSQL所做的工作就非常简单,它会直接替换成最大可取值或最小可取值。
或许有人注意到,我们在使用phpmyadmin的时候,如果选择INT类型,那么后面有一个可选长度。不过,千万不要被这个数值所迷惑,因为它的实际功能并非指定该INT类型的长度,而是最大显示宽度(M:Maximum Display Width),仅仅用于查询数据时可以把查询结果按照你所指定的宽度进行显示,最主要的用途是为了排版需要。虽说是这样,但在一些很少见的特定场合(MYSQL在执行一些需要借助于临时数据表才能完成的复杂查询)里,临时数据表的数值有可能会被截短并导致最终结果不正确。因此,除非你与数据库所有的操作都在命令行下执行,否则,还是建议留空。

INT 类型 该类型的实际含义
 Tinyint(m) 8位整数,占用1个字节(-128~+127)
 smallint(m) 16位整数,占用2个字节(-32768~+32767)
 medimumint(m) 24位整数,占用3个字节(-8388608~+8388607)
 int(m),integer(m) 32位整数,占用4个字节(-2147483648~+2147483647)
 bigint(m) 64位整数,占用8个字节(-9.22E+18 ~ +9.22E+18)
 serial 这其实是bigint auto_increment not null primary key的简写

上面tinyint(m)括号中的m,就是上文所指的最大显示宽度。最后一个serial含义里的auto_increment,代表了该字段是自增字段,即,往有该属性的字段里插数据时,系统会自动把该字段的当前最大值加上1后存进去。 一般而言,该属性往往用于主键字段。在使用该属性时应当注意以下几个问题。
1、该属性必须与NOT NULL、primary Key 或者 Unique属性同时使用。
2、每个数据表只能存有一个auto_increment属性的数据列
3、该属性一般是在进行数据插入时,没有明确指定值或者指定值为NULL时,才起作用。如果指定了值,并且该值还没有出现过,MYSQL将使用该值插入,以生成一条新记录。这时候就有两种情况:a)原有的数据是1~100,后来删除了20~80的内容,即数据库里只存在1~19,81~100的数据,当插入ID为20的数据时,数据库还是会按照规则,把20这条记录插进去,并不会报错,自增值仍然是100,下次正常插入时,还是会默认使用101这个值。b)原有的数据是1~100,我插入ID为1000的数据时,不会报错,但自增值变为1000,下次插入数据从1001起算。(啰嗦了点,但应该记住)
4、如果想知道刚刚插入的数据值是多少,在插入数据后,可以使用select last_insert_id()语句获取。在PHP中,有一个函数是:mysql_insert_id(),该函数不是很建议使用,因为它返回的数据是INT型,如果auto_increment所在的数据列类型是bigint,而且实际值已经超过int类型最大值的话,mysql_insert_id()返回的值,将不正确。
5、如果auto_increment计数器达到了最大值(即该字段所允许的最大值),将不再递增,因此数据插入将无法执行。其实是到了最大值后,MYSQL会永远将该字段的最大值往数据库里插,因此造成MYSQL报:该数据列已存在的错误。
6、如果在可行范围内,或者预计数量会很大的情况下,尽量使用你想要设定的数据类型的再上一层类型,但尽量不要太夸张。比如你预计你的用户数不会超过1000000万,表面上medimum无符号已经够用了,但这时候,仍然建议你使用int型,以防万一。

打字很累,剩下的留到以后慢慢讲。。。

差点忘了。。。还有个BIT和BOOL,在MYSQL中,关键词BOOL是TINYINT的同义词,在5.0.2以及以前的版本中,BIT也是如此。但是从5.0.3开始,BIT不再是TINYINT的同义词,而是一种可以存储多达64位二进制数值的新数据类型。这个在以后会单独介绍,这里一笔带过先。

Tags: database, mysql, 连载

精通MYSQL数据库——连载五

明天,就是俺结婚2周年的纪念日了,为了感谢大家的支持,所以。今天再开放一篇连载。黑黑

介绍完MYSQL所支持的一些数据表类型,再介绍一下数据表文件的存放等资料。

MYSQL对于数据表的存放一般而言都是很有规律的,在*nix系统下面,通常在/var/lib/mysql子目录,而在windows平台下一般都在mysql安装目录下的子目录/data/里。

(写了一半,发现都需要用到数据存放目录,现在假设数据存放目录为/data/)

一般而言,每一个数据表都有一个和表名对应的frm文件,而这些数据表都是存储在以它本身所在数据库为名的目录里。例如:User数据库下的members表,一般都存储在数据库目录下的/User/下,名字为members.frm(全路径为:/data/User/members.frm)。frm文件是整个数据库的结构定义和设置。

如果是myisam数据表,那么还会创建两个以数据表命名的文件,*.MYD,*.MYI,其中MYD文件用来存放MYISAM数据表的数据,而MYI文件用来存放索引(该表的所有索引)。

如果是innoDB数据表的话,就需要根据MYSQL配置文件中的innodb_file_per_table的选项设置情况而定。它既可以各自存为一个文件,也可以统一存放在所谓的表空间(tablespace)里。表空间的存放位置和名字由配置决定。如果没有做任何设置的话,默认是innodb数据表的数据和索引存放在/data/dbname/tablename.idb文件里,而把表空间和撤销日志(undo log)存放在/data/ibdata1,/data/ibdata2/...等文件里,而把innodb的日志数据存放在/data/ib_logfile0 ,/data/ib_logfile1这样有规则的文件里。

在如今的版本里,如果你定义了触发器,那么它们存放在/data/databasename/tablename.TRG文件里。新版本据说可能会发生变化。

Tags: mysql, database, 连载

精通MYSQL数据库——连载二

(今天晚上要读书,所以先发上来)

 昨天我们讲的是myisam表的特性,今天我们来讲讲innodb的一些特性。

之所以要采用innodb,是因为innodb有一些新的特性,而这些特性又是myisam所不具备的,它们是:事务、数据行级锁定、外键约束、崩溃恢复
看到上面这些特性,你是不是基本了解了innodb所应用的范围了?是的,innodb所具备的这些特性,使得mysql即使在高端应用也有了用武之地,特别是在处理类似银行这些对事务非常关心,也非常重要的场合(存钱取钱以及转帐等),下面就对这些特性进行简单介绍。
在介绍特性之间,先说明一下,innodb虽然一直是MSYQL的集成组件之一,但事实上,innodb的驱动的研发和收费技术支持都是来自innodb公司:http://www.innodb.com,这可是一家独立的公司。
事务:在innodb里所有的操作都可以被看成是在执行一个事务,它允许把几条有内在逻辑关系的SQL当成一个整体来执行。所以执行期间发生错误,则所有的命令会全部失效,就好象从未执行过任何SQL一样,而不仅仅是导致错误的那一条命令。正因为这样,所以事务功能相对增强了数据库的安全性。mysql支持全部的4种事务级别(READ UNCOMMITTED,READ COMMITED,REPEATABLE READ , SERIALIZABLE)
数据行级锁定:在执行事务时,innodb表的驱动程序会使用内置的行级锁定机制,而不是采用mysql自身的行级锁定机制。也就是说即使在执行事务时,其他进程仍然可以访问它,因为被锁定的仅仅是那些正在接收事务处理的记录。这与mysql的lock table不一样,lock table执行完后,整个表都被锁定了。这两种方式的对比可以让你看出,如果有一大堆人在处理一个很大的数据表,孰优孰劣一看便知。并且,innodb的这个驱动相对比较先进的就是,它能够自动识别“死锁”(所谓死锁,就是两个进程各战胜一项对方需要的资源,同时又在等待对方先释放所占用的资源,结果导致两个进程都不能执行),并自动终止两个进程中的一个。这才是innodb的强项。
外键约束:如果在数据表间定义了关联,innodb驱动将自动保证数据表的引用一致性,即便在执行过delete后也能同样保持。也就是说,不可能出现在A表的记录引用B表一条并不存在的记录,这就是所谓的:外键约束
崩溃恢复:理论上,在数据库发生崩溃后,只要计算机的文件系统没有被破坏,innodb数据表能够迅速地自动恢复到一个稳定可用的状态。说明一下,这只是理论上,具体怎么样,我没有测试过,也没有搜索到相关文章,如果有人搜索到相关的资料,请告知,以便我更新一下,谢谢。
 
说了这么多的特性,下面也要谈谈它的缺点,毕竟凡事都有双面性,有优点自然也会存在缺点,否则,谁还会用myisam?
使用innodb有以下几个缺点:
1、表空间的管理。与myisam分成三个文件的存储方式不一样,innodb把所有的数据、索引、结构都存在了一个表空间里。当然,表空间可以是一个或多个文件组成,也就是说这些文件组成了一个虚拟的文件系统。然而问题就出在这里,这些文件被创建后只能增长,不能缩小。如果想复制innodb表,只有使用mysqldump来进行处理,而myisam在停掉数据库后,直接复制就可以了(好象到了4.1或5.0后,这样的直接复制好象不行了?我是指两个表的设置如果不一样的话)
2、数据记录的长度。innodb的单条记录最多占用8000个字节。这个限制不包括text和blob等类型字段,事实上,这此字段只有前512个字节和其他数据存在数据库里,超过这个长度的内容都是被存储在上面所说的“虚拟文件系统——表空间”的其他文件里面。在这里,有一个回复,也可以参考一下,虽然不一定完全正确:http://imysql.cn/node/548,呵呵。
3、存储空间。在内容相同的情况下,一般来说innodb所占用的空间要比myisam所占用的大的多,最多时,可能会有两倍。
4、全文索引。这恐怕是它最大的缺憾了,innodb不支持full-text index。
5、GIS数据。存储和读取这个,还是myisam来的更方便一点,所以innodb也不支持它。
6、COUNT相关。innodb在处理SELECT COUNT(*) FROM table的时候,比myisam慢得多,这主要是因为它支持事务。可是,我在用sql server的时候也没有慢很多嘛。不知道它何时能够被解决,否则在内容较大的时候,处理分页就烦了。
7、表锁定。因为innodb有自己的表锁定算法,所以想使用表锁定功能时,用innodb所支持的select .. for update或select .. IN share mode,而不要使用mysql 自带的lock table。
8、虽然有这么多好处,可惜mysql这张表,还是得用myisam格式。而不能使用innodb
9、费用。。。。对于我们个人来说,我们只需要使用免费的mysql,而不是使用商业版的mysql,那么收费就与我们无缘了。至于商业应用嘛,那,钱是少不了的,听说,如果在mysql许可证里加上innodb支持,将收取双倍费用。好恐怖。。。
 
上面的这些也是我在参考书本后,进行的整理,否则,凭我这些小小的经验,怎么可能了解这么多?

Tags: mysql, database, innodb, myisam, 连载

单位培训了MYSQL

 单位今天请MYSQL公司的人来进行了简单的辅导和介绍。上午的我没有参加,下午的因为涉及到了一些SQL优化之类的,同事让我也听听学习学习。

一开始的时候讲了一大堆存储的事,可惜都是那种很空洞的感觉。不过想想也是,这种利用PPt来进行介绍的,怎么可能介绍的很详细,当时就有一种受骗的感觉。呵呵

这种课程听的再多恐怕也是和没听没啥区别吧。

唯一有印象的就是,数据库的设计规范,但也没有讲什么具体的,只是简单的说了一下:
1、能用int的,坚决不用bigint
2、如果能够基本确定长度,那就写上固定的varchar(10),而不是varchar(255),虽然最终存储的长度一样。
3、不要随便为某个字段增加索引,可以通过一句SQL来分析一下表(汗,忘了是什么命令了。啥时候有空翻翻手册应该就知道了)
4、如果可能,请尽量为字段设定NOT NULL(毕竟使用BTree的索引时,NULL是不在检索范围之内的)

反正,就感觉,我们里面的一些同事设计的表,完全符合他提出的这些问题,我好满足啊。他们主动要求,表一定要default NULL。

还有对我有印象的就是,如果某字段的值几乎一致,比如:a_123,a_456,建议使用前缀索引(MYSQL4好象没有这个?)不过确实这个从来没有注意过。。。

其他的什么分表存储,水平,垂直,都只是空泛的介绍。而没有实质性的东西。。。

当然,主要是因为这其中的大部分知识,我还是略有所知的。。。

总算还是略有收获,没有完全浪费1小时左右的时间。不过,这位介绍人员的介绍有点生疏,黑黑。。。害羞?还是初次从后台走向前台?不得而知。。。

Tags: mysql, database, 存储

Records:2312345