MYSQL:视图的algorithm概念

/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<title>新建网页</title>
<meta http-equiv="Content-Type" content="text/html; charset=GBK" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<script type="text/javascript">

</script>

<style type="text/css">
</style>
</head>
<body>
the reason is which encoding you choose not match to the decoding!
<br />
声音不能太大!
</body>
</html>

 

/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it 
**/

<?php
$conn = mysql_connect('localhost','root','111111');
$sql = 'use test';
mysql_query('set names utf8');
/*

分析: 我的网页是utf8,因此client是utf8
我的表是utf8,因此,连接器,utf8
返回值也是 utf8

因此, set names utf8;


牵涉到数据库,想不乱码

1:正确指定客户端的编码
2:合理选择连接器的编码
3:正确指定返回内容的编码

并与01.html中说 结合起来
"网页文件本身编码, meta信息, client/connection/results的指定"
如果都保持一致,断无乱码可能!

如有,请检查自已的错!

*/

 

 

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh-CN">
<head>
<title>新建网页</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="description" content="" />
<meta name="keywords" content="" />
<script type="text/javascript">

</script>

<style type="text/css">
</style>
</head>
<body>
the reason is which encoding you choose not match to the decoding!
<br />
声音不能太大!
</body>
</html>

 

/**
燕十八 公益PHP培训
课堂地址:YY频道88354001
学习社区:www.zixue.it
**/

 

mysql> set names gbk;
Query OK, 0 rows affected (0.02 sec)

mysql> #建一张简单的查询视图,不用临时表,只用条件合并
mysql> create view v1
-> as
-> select * from goods where shop_price>300;
Query OK, 0 rows affected (0.56 sec)

mysql> #查询视图
mysql> select goods_id,goods_name,shop_price from v1 where shop_price < 500;
+----------+------------+------------+
| goods_id | goods_name | shop_price |
+----------+------------+------------+
| 8 | 飞利浦9@9v | 399.00 |
+----------+------------+------------+
1 row in set (0.11 sec)

mysql> #总的条件,就是>300,<500.
mysql> #这个简单的查询还建临时表的话,开销有点大.
mysql> #这时我们可以指定algorithm选项为merge
mysql> create view v2
-> \c
mysql> create algorithm=merge view v2
-> as
-> select * from goods where shop_price>300;
Query OK, 0 rows affected (0.17 sec)

mysql> select goods_id,goods_name,shop_price from v2 where shop_price < 500;
+----------+------------+------------+
| goods_id | goods_name | shop_price |
+----------+------------+------------+
| 8 | 飞利浦9@9v | 399.00 |
+----------+------------+------------+
1 row in set (0.01 sec)

mysql> #虽然从结果上看不出区别,但是这个v2视图,并没有建立临时表.
mysql>
mysql> #有的时候,必须建临时表
mysql> #比如,每个栏目的平均商品价格
mysql> create algoithm=temptable view v3
-> as
-> select goods_id,cat_id,goods_name,shop_price
-> from goods
-> order by cat_id asc,shop_price desc;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'algoithm=temptable view v3
as
select goods_id,cat_id,goods_name,shop_price
fro' at line 1
mysql> create algorithm=temptable view v3
-> as
-> select goods_id,cat_id,goods_name,shop_price
-> from goods
-> order by cat_id asc,shop_price desc;
Query OK, 0 rows affected (0.16 sec)

mysql> #这张表,明确指定了生成临时表
mysql> #如果我拿不准用什么,algorithm=undefined,让系统为我们做决定.
mysql> select * from v3;
+----------+--------+------------------------------+------------+
| goods_id | cat_id | goods_name | shop_price |
+----------+--------+------------------------------+------------+
| 16 | 2 | 恒基伟业G101 | 823.33 |
| 22 | 3 | 多普达Touch HD | 5999.00 |
| 32 | 3 | 诺基亚N85 | 3010.00 |
| 17 | 3 | 夏新N7 | 2300.00 |
| 9 | 3 | 诺基亚E66 | 2298.00 |
| 24 | 3 | P806 | 2000.00 |
| 21 | 3 | 金立 A30 | 2000.00 |
| 31 | 3 | 摩托罗拉E8 | 1337.00 |
| 10 | 3 | 索爱C702c | 1328.00 |
| 13 | 3 | 诺基亚5320 XpressMusic | 1311.00 |
| 11 | 3 | 索爱C702c | 1300.00 |
| 12 | 3 | 摩托罗拉A810 | 983.00 |
| 19 | 3 | 三星SGH-F258 | 858.00 |
| 15 | 3 | 摩托罗拉A810 | 788.00 |
| 8 | 3 | 飞利浦9@9v | 399.00 |
| 20 | 3 | 三星BC01 | 280.00 |
| 18 | 4 | 夏新T5 | 2878.00 |
| 14 | 4 | 诺基亚5800XM | 2625.00 |
| 33 | 4 | 金立910浪漫镶钻手机 | 1233.00 |
| 23 | 5 | 诺基亚N96 | 3700.00 |
| 7 | 8 | 诺基亚N85原装立体声耳机HS-82 | 100.00 |
| 3 | 8 | 诺基亚原装5800耳机 | 68.00 |
| 4 | 8 | 诺基亚N85原装充电器 | 58.00 |
| 6 | 11 | 胜创KINGMAX内存卡 | 42.00 |
| 5 | 11 | 索爱原装M2卡读卡器 | 20.00 |
| 25 | 13 | 小灵通/固话50元充值卡 | 48.00 |
| 26 | 13 | 小灵通/固话20元充值卡 | 19.00 |
| 29 | 14 | 移动100元充值卡 | 90.00 |
| 30 | 14 | 移动20元充值卡 | 18.00 |
| 27 | 15 | 联通100元充值卡 | 95.00 |
| 28 | 15 | 联通50元充值卡 | 65.00 |
+----------+--------+------------------------------+------------+
31 rows in set (0.06 sec)

mysql> #要想不乱码,需要指定客户端的编码,
mysql> #让连接器不理解错误
mysql> #这样就不会存入错误数据
mysql> #往回取的时候,我们还要告诉连接器,如果你从服务返回,应该给我转什么格式
mysql> #一共是3个参数, 客户端的发送的编码,
mysql> #连接器使用的编码
mysql> #获取的返回数据的编码
mysql>
mysql>
mysql> #当前的情况是, 客户端GBK, 服务器最终存UTF*
mysql> #明确的告诉服务器
mysql> #我的客户端是GBK的
mysql> set character_set_client gbk;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'gbk' at line 1
mysql> set character_set_client=gbk;
Query OK, 0 rows affected (0.03 sec)

mysql> #再告诉连接器,使用utf8
mysql> set character_set_connection=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> #再告诉,如果返回值,请返回GBK的结果
mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)

mysql> desc test15;
+--------+------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+--------+------------+------+-----+---------+-------+
| sname | varchar(5) | YES | | NULL | |
| gender | tinyint(4) | YES | | NULL | |
+--------+------------+------+-----+---------+-------+
2 rows in set (0.31 sec)

mysql> insert into test15 values ('编码不乱',1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test15;
+----------+--------+
| sname | gender |
+----------+--------+
| 张三 | 1 |
| 韩梅梅 | 0 |
| 李宇春 | 2 |
| 编码不乱 | 1 |
+----------+--------+
4 rows in set (0.02 sec)

mysql> #但是,我客户端传的是GBK,但我偏对方,是UTF8
mysql> set character_set_client=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test15 values ('编码乱不乱',1);
ERROR 1366 (HY000): Incorrect string value: '\xB1\xE0\xC2\xEB\xC2\xD2...' for column 'sname' at row 1
mysql> #此时,"编码乱不乱"对应的GBK的内码,转成UTF8压根就出错,不允许插件.
mysql> #我们服务器如果检测不严格,可以插入,但会丢失数据.
mysql> set character_set_client=gbk;
Query OK, 0 rows affected (0.02 sec)

mysql> #我偏要对方还给我的数据是UTF8
mysql> set character_set_results=utf8;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test15;
+--------------+--------+
| sname | gender |
+--------------+--------+
| 寮犱笁 | 1 |
| 闊╂姊? | 0 |
| 鏉庡畤鏄? | 2 |
| 缂栫爜涓嶄贡 | 1 |
+--------------+--------+
4 rows in set (0.00 sec)

mysql> #请问,我再插入数据
mysql> insert into test15 values ('编码乱不乱',1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test15;
+-----------------+--------+
| sname | gender |
+-----------------+--------+
| 寮犱笁 | 1 |
| 闊╂姊? | 0 |
| 鏉庡畤鏄? | 2 |
| 缂栫爜涓嶄贡 | 1 |
| 缂栫爜涔变笉涔? | 1 |
+-----------------+--------+
5 rows in set (0.00 sec)

mysql> set character_set_results=gbk;
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test15;
+------------+--------+
| sname | gender |
+------------+--------+
| 张三 | 1 |
| 韩梅梅 | 0 |
| 李宇春 | 2 |
| 编码不乱 | 1 |
| 编码乱不乱 | 1 |
+------------+--------+
5 rows in set (0.00 sec)

mysql> #再看另一种情况
mysql> #声明客户端是GBK
mysql> set character_set_client=GBK:
-> \c
mysql> set character_set_client=GBK;
Query OK, 0 rows affected (0.00 sec)

mysql> #再声明连接器是GBK
mysql> set character_set_connection=GBK;
Query OK, 0 rows affected (0.00 sec)

mysql> #再声明返回值是GBK
mysql> set character_set_results=GBK;
Query OK, 0 rows affected (0.02 sec)

mysql> #如上操作,会不会乱码?
mysql> insert into test15 values ('真不乱?',1);
Query OK, 1 row affected (0.03 sec)

mysql> select * from test15;
+------------+--------+
| sname | gender |
+------------+--------+
| 张三 | 1 |
| 韩梅梅 | 0 |
| 李宇春 | 2 |
| 编码不乱 | 1 |
| 编码乱不乱 | 1 |
| 真不乱? | 1 |
+------------+--------+
6 rows in set (0.00 sec)

mysql> set charset_set_connection=latin;
ERROR 1193 (HY000): Unknown system variable 'charset_set_connection'
mysql> set character_set_connection=latin1;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test15 values ('还不乱?',1);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test15;
+------------+--------+
| sname | gender |
+------------+--------+
| 张三 | 1 |
| 韩梅梅 | 0 |
| 李宇春 | 2 |
| 编码不乱 | 1 |
| 编码乱不乱 | 1 |
| 真不乱? | 1 |
| ???? | 1 |
+------------+--------+
7 rows in set (0.00 sec)

mysql> #latin1小,GBK大,就像大鱼过小渔网的时间,丢了块肉.
mysql> #这次的乱码能否修复?
mysql> # 不能
mysql> # 服务器 >= conntion>=client
mysql> #再回头看: 太巧了,刚才. client,conn,results都是GBK.
mysql> #如果3者,都是GBK,可以简写
mysql> #简写成set names gbk
mysql> exit

 

 

编码问题:


计算机里,只有010101
而人的世界里,有文字,有图片,有声音....


01 ---> 文字对应起来


人为的约定

65->A
66->B
...
...


0100 0001 [A,65]

2进制编码 到 字符的映射,就是字符集.

 

看自己的键盘

A-Z
a-z
0-9
+-*/&^%

不超过127个.

美国人在造计算机的时候,就没考虑到,还有其他的字符.

 

 

 

 

1111 1111
0000 0000 256种值,

1个字节8个位 就足够了.

事实上,7个位就够了,因为7个位,可能表示128种变化.


ascii
0-127来表示

0xxx xxxx ,最高位始终是0


到了中国

常用汉字3000多,生僻汉字不用说.


1个字节,够不够?
答:不够,任你变,不过256种.

思考:用2个字节来表示
[][]

0000 0000 0000 0000
1111 1111 1111 1111
0-> 65535,6万多种组合,够用了.

GB2312字符集

[202 197] 假如代表 中
[69 197] 代表 ?
[200 101]

202 197 69 197 200 101....

69和197整个理解,还是单理解成E

歧义: 就是因为单字节的小于127的值,正好是ascii的值.
如果就严格的2字节绑定,理解为中文,
则gb2312不能识别英文了.


问: 如何兼容ascii,又能双字节表示中文?

ascii 0-127

0xxxx xxxx

干脆 gb2312完全不占用0-127.

 

我的组合来自于
[129-255][129-255]


130 140 97 95 134 198
看:能几个中文,几个英文?


但是,中文的组合数,也少了.
只能组合10000+,
事实上,GB2312只能容纳6000多字

 

GBK还是双字节,如何扩充容量?
答:

GBK的第2低,低位,不再局限于129-255了,<127的也能用

140 35 65 179 82
问:几个中文,几个英文?

总结: 碰到>128的,就再往后找一字节.2字节理解成中文.
继续找,

找到>128的,就带个家属. ,127的,就单身

 

中国 GBK
[137][134] ->中

到了日本呢?

[137][134]-> す ふに 呆

jis


ANSI 代表本地字符集

在中文操作 GBK
在日本 JIS


中文-->
中华人民颐和园

拿到日本-->读-->乱?


解决了多字节之后, 又相来一个问题----世界各国的字符集,兼容问题.

 

终极大招: Unicode

 

unicode是一个世界通用的码表

00000000 0000 0041 -->A
......................中
..................->す


全世界的范围的字符,统一分配一个标号.

这样,不会乱了.


unicode用4个字节,来编号

2^32 ,40多亿, 天文数字. 足够用了


但我们常用的,集中在 前65535个标号里.
2个字节就够了.

但是,unicode只负责分配编号用的,而且都用4个字节来分配编号.

你负责编号,

我负责在不改变你编号的基础上,简化字节.

0000 0000 0000 0000 0000 0000 0000 0041 ->A

0000 0041 ->A


把高位浪费的0值,用一定的规则舍弃.


形成的编码方式 ,

 

unicode与utf-8的关系

就像原文件 --> 压缩文件的关系.

问: 给定unicode字符---> utf-8的二进制值?

 

utf-8的二进制值?--->unicode字符

 

utf8占几个字节呢?

不可能定长,否则压缩还有什么意义?

变长,如何确定字符的边界?


23 179 234 123


如何截取utf8(各国语言都有),无乱码?
答: 从头开始,取1个字节.
通过位运算,计算连续的1的个数.

如为0,则截取1个字节
如为N,则截取N个字节

 

从容量上来看

GB2312 < GBK < UTF-8

 


问: GBK中文经常在java中,被转为utf-8?
答:怎么转的?

GBK 也是和unicode有对应关系的.

GBK->unicode->utf-8


乱码是如何形成的?

 

utf-8-->转成gb2312,
容量大 容量小
丢失了字节?


连接器的特性: 连接客户端与服务器

客户端的字符先发给连接器

连接器选择一种编码将其转换,临时存储

再次转换成 服务器需要的编码,并存储在服务器

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

posted on 2012-11-03 11:31  besile  阅读(1370)  评论(0)    收藏  举报