写程序时如果用到数据库建议向sqlite看齐,sqlite可没有enum.
Enum: 多用于固定不变的一些数据内容
比如:周一,周二,周三,,,,,,周日
Tinyint: 多用于表示状态(0,1,2,3....), 性能上来说不比 enum差.
Enum存取数据内容时是整型数据,也会把数据转为字符串来处理.
Tinyint存取是整型就是整型.
另外:
数据表有字段: Status enum('0','1','2','3') default 0;
update table set `Status`=0; //这时查看数据内容结果 Status='';
如果Status tinyint default 0; //同样操作数据内容就是 Statsus=0;
-------------------------------------------------------------------
mysql没有必要枚举整型
有些人习惯地把一些状态表示为整型,在mysql存储这些整型时,却转化成字符串,存在了枚举型的列中。这是不必要的。因为在mysql存储这
些枚举字符串时是把这样字符串做一个序列(index),然后存储相应的index值,比如
Enum_value index
NULL NULL 如果NULL是被允许的话
'' 0 一切在在插入时,被视为非法值的字符串,插入的都为空
'a' 1
'b' 2
... ...
也就是说,我们在插入值时,是插入的'a','b'等等字符串,但Mysql真正存储是则是右边的index.如果真得左边的ENUM也为整型值,则是不可取的。因为:
If you store a number into an ENUM column, the number is treated as an index, and the value stored is the enumeration member
with that index. (However, this does not work with LOAD DATA, which treats all input as strings.) It's not advisable to
define an ENUM column with enumeration values that look like numbers, because this can easily become confusing. For example,
the following column has enumeration members with string values of '0', '1', and '2', but numeric index values of
1, 2, and 3.
ENUM的最多的个数也证明了这一点。
An enumeration can have a maximum of 65,535 elements.
同时,都知道程序的需求变化很快,尤其是WEB类的脚本程序。ENUM在表示状态时,也会面临着扩展状态所带来困扰。你必须改变表结构新的值被允许存入。
建议:表示状态类的最好用TINYINT。枚举不是不行,但至少它不是最好。
2008年12月12日星期五
2008年11月13日星期四
消重 Mysql row data 记录
今天处理数据时由于 loading data 重复导致数据内容重复,不得已要进行消重.
方法如下:
1.先找出重复数据内容的ID,把ID存文件或是临时数据表
装数据内容存在test DB 中,为了删除方便存两列数据内容:SQL, ID
下面例子,从Redirect_Log表中找出重复的ID,存在test.tmp_delete_repeat_data_081112表中.
说明:group by SessionID,VisitTime,Status,SourceSite,CurRandStr 是因为我的这个数据表必须这些字段一起 distinct 才可能标示唯一性.
2.执行SQL语句进行删除这些重复的ID
首先把test.tmp_delete_repeat_data_081112 表的数据内容倒出到文件
然后把文件内容load进mysql就可以了
方法如下:
1.先找出重复数据内容的ID,把ID存文件或是临时数据表
装数据内容存在test DB 中,为了删除方便存两列数据内容:SQL, ID
下面例子,从Redirect_Log表中找出重复的ID,存在test.tmp_delete_repeat_data_081112表中.
create table test.tmp_delete_repeat_data_081112
select concat("delete from `Redirect_Log` where id=",id,";") sqls, id
from
`tracking_smarter`.Redirect_Log
group by SessionID,VisitTime,Status,SourceSite,CurRandStr
having count(*)>1
说明:group by SessionID,VisitTime,Status,SourceSite,CurRandStr 是因为我的这个数据表必须这些字段一起 distinct 才可能标示唯一性.
2.执行SQL语句进行删除这些重复的ID
首先把test.tmp_delete_repeat_data_081112 表的数据内容倒出到文件
select sqls into outfile '/tmp/w.sql' from tabl1;
然后把文件内容load进mysql就可以了
mysql -uroot -p tracking < /tmp/w.sql
2008年11月9日星期日
GROUP_CONCAT()妙用
GROUP_CONCAT()是MySQL数据库提供的一个函数,通常跟GROUP BY一起用,具体可参考MySQL官方文挡:http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat。
先来看一下这个函数的语法:
下面就演示一下这个函数所带来的方便之处,首先建立一个学生选课表student_courses,并填充一些测试数据。
若要查找学生ID为2所选的课程,则使用下面这条SQL:
输出结果有3条记录,说明学生ID为2的学生选了3、4、5这3门课程。
放在PHP里,必须用一个循环才能取到这3条记录,如下所示:
而如果采用GROUP_CONCAT()函数和GROUP BY语句就显得非常简单了,如下所示:
看见没,在PHP里就不用循环了,如下所示:
当然分隔符还可以自定义,默认是以“,”作为分隔符,若要改为“|||”,则使用SEPARATOR来指定,例如:
除此之外,还可以对这个组的值来进行排序再连接成字符串,例如按courses_id降序来排:
先来看一下这个函数的语法:
GROUP_CONCAT([DISTINCT] expr [,expr ...]
[ORDER BY {unsigned_integer | col_name | expr}
[ASC | DESC] [,col_name ...]]
[SEPARATOR str_val])
下面就演示一下这个函数所带来的方便之处,首先建立一个学生选课表student_courses,并填充一些测试数据。
CREATE TABLE student_courses (
student_id INT UNSIGNED NOT NULL,
courses_id INT UNSIGNED NOT NULL,
KEY(student_id)
);
INSERT INTO student_courses VALUES (1, 1), (1, 2), (2, 3), (2, 4), (2, 5);
若要查找学生ID为2所选的课程,则使用下面这条SQL:
mysql> SELECT student_id, courses_id FROM student_courses WHERE student_id=2;
+------------+------------+
| student_id | courses_id |
+------------+------------+
| 2 | 3 |
| 2 | 4 |
| 2 | 5 |
+------------+------------+
3 rows IN SET (0.00 sec)
输出结果有3条记录,说明学生ID为2的学生选了3、4、5这3门课程。
放在PHP里,必须用一个循环才能取到这3条记录,如下所示:
<?php
...
foreach ($pdo->query("SELECT student_id, courses_id FROM student_courses WHERE student_id=2") as $row) {
$result[] = $row['courses_id'];
}
...
?>
而如果采用GROUP_CONCAT()函数和GROUP BY语句就显得非常简单了,如下所示:
mysql> SELECT student_id, GROUP_CONCAT(courses_id) AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id;
+------------+---------+
| student_id | courses |
+------------+---------+
| 2 | 3,4,5 |
+------------+---------+
1 row IN SET (0.00 sec)
看见没,在PHP里就不用循环了,如下所示:
<?php
...
$row = $pdo->query("SELECT student_id, GROUP_CONCAT(courses_id) AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id");
$result = explode(',', $row['courses']);
...
?>
当然分隔符还可以自定义,默认是以“,”作为分隔符,若要改为“|||”,则使用SEPARATOR来指定,例如:
mysql> SELECT student_id, GROUP_CONCAT(courses_id SEPARATOR '|||') AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id;
+------------+-----------+
| student_id | courses |
+------------+-----------+
| 2 | 3|||4|||5 |
+------------+-----------+
1 row IN SET (0.00 sec)
除此之外,还可以对这个组的值来进行排序再连接成字符串,例如按courses_id降序来排:
mysql> SELECT student_id, GROUP_CONCAT(courses_id ORDER BY courses_id DESC) AS courses FROM student_courses WHERE student_id=2 GROUP BY student_id;
+------------+---------+
| student_id | courses |
+------------+---------+
| 2 | 5,4,3 |
+------------+---------+
1 row IN SET (0.02 sec)
订阅:
博文 (Atom)