@a5635268
2015-09-23T00:25:46.000000Z
字数 6473
阅读 1440
Mysql
视图是表的一个映射,是一张虚表,在结构上视图和普通的表没什么区别,一样可以用sql语句来增删改查;
视图创建后是一直存在数据库内
语法
CREATE [ALGORITHM]={UNDEFINED|MERGE|TEMPTABLE}]VIEW 视图名 [(字段清单)]AS SELECT 语句[WITH [CASCADED|LOCAL] CHECK OPTION];
Merge
-- Merge,意味着视图只是一个规则,语句规则, 当查询视图时,把查询视图的语句(比如where那些)与创建时的语句where子句等合并,分析.再形成一条新的select语句.-- 创建视图的语句:CREATE altorethm=merge VIEW `g2` AS SELECT `goods_id`,`cat_id`,`goods_name`,`shop_price` FROM `goods` ORDER BY `cat_id` ASC,`shop_price` DESC;--查询视图的语句:SELECT * FROM `g2` GROUP BY `cat_id`;-- 最终执行的语句:SELECT `goods_id`,`cat_id`,`goods_name`,`shop_price` FROM `goods` GROUP BY `cat_id` ORDER BY `cat_id` ASC,`shop_price` DESC;
temptable
-- temptable是根据创建语句瞬间创建一张临时表,然后查询视图的语句从该临时表查数据.CREATE ALTORETHM=TEMPTABLE VIEW `g2` AS SELECT `goods_id`,`cat_id`,`goods_name`,`shop_price` FROM `goods` ORDER BY `cat_id` ASC,`shop_price` DESC;-- 查询视图的语句:SELECT * FROM `g2` GROUP BY `cat_id`;-- 最终执行的2句话: 取数据并放在临时表,然后去查临时表.
with [cascaded] check option
mysql> create view v1 asselect * from goods where stock > 100 WITH check OPTION; -- 使用了with check option 这个选项那后面对视图的插入只限于包含stock的表;Query OK, 0 rows affected-- ↓↓ 只允许插入包含stock字段的sqlmysql> INSERT into v1(gname) values('zhouzhou');1369 - CHECK OPTION failed 'test.v1'mysql> INSERT into v1(gname,stock) values('zhouzhou',8000);Query OK, 1 row affected-- ↓↓ 不影响删除mysql> delete from v1 where gname = 'ganggang';Query OK, 2 rows affected-- ↓↓ 貌似也不影响更新mysql> update v1 set gname = 'test' where gid = 11;Query OK, 1 row affectedRows matched: 1 Changed: 1 Warnings: 0-- 其实错误,因为更新后查询出来的表字段里面能查询到stock > 100;所以可以更新;-- ↓↓ 如果更新后的结构不能再通过stock>100来查询就不能进行更新;mysql> update v1 set stock = 99;1369 - CHECK OPTION failed 'test.v1'
with local check option
以后研究... wait for
Example1: 单表创建视图
CREATE VIEW v1 ASSELECTuser_id, nickname, IF (sex = 1, '男', '女') as sex, user_moneyFROMusersORDER BYuser_money DESCLIMIT 10;-- question: 该视图不能被更新?update v1 set user_money=5000 where user_id = 2659;[Err] 1288 - The target table v2 of the UPDATE is not updatable
Example1: 多表创建视图
CREATE VIEW v3 ASSELECTu.user_id,nickname,lhmoney,user_recommend,goodsFROMusers AS uJOIN COMMENT AS c ON u.user_id = c.user_idORDER BYuser_id ASC WITH CASCADED CHECK OPTION;
创建视图时注意:
[Err] 1349 - View's SELECT contains a subquery in the FROM clause -- 不能在SELECT的FROM子句中包含子查询。
mysql> drop view v1; -- drop view 视图名;Query OK, 0 rows affected
CREATE OR REPLACE语句非常灵活,在视图存在的情况下可对视图进行修改,视图不在的情况下可创建视图,其基本用法和CREATE VIEW 几乎一致
CREATE OR REPLACE ALGORITHM=TEMPTABLEVIEW v2(uid,nickname,money) ASSELECTuser_id,nickname,user_moneyFROMusersORDER BYuser_money DESCLIMIT 10;
AlTER VIEWv3(uid,cid,nickname,lhb,content,goods) ASSELECTu.user_id,user_comment_id,nickname,lhmoney,user_recommend,goodsFROMusers AS uJOIN COMMENT AS c ON u.user_id = c.user_idORDER BYuser_id ASC WITH CASCADED CHECK OPTION;
视图是表的查询结果映射,那原表的数据改变了,视图也当然会跟着做相应的改变。
但,如果视图里面的数据改变了呢?
首先,视图增删改是会影响表的;也就是说,可以在诸如UPDATE、DELETE或INSERT等语句中使用它们,以更新基表的内容。但是,视图并不是总是能增删改的。对于可更新的视图,在视图中的行和基表中的行之间必须具有一对一的关系。还有一些特定的其他结构,这类结构会使得视图不可更新。更具体地讲,如果视图包含下述结构中的任何一种,那么它就是不可更新的:
mysql> update v4 set sex=5 where user_id = 32; -- 一定程度上保证了基表数据的安全性1288 - The target table v4 of the UPDATE is not updatable
关于视图的可插入性:insert
如果视图满足关于视图列的下述额外要求,可更新的视图也是可插入的:
+ 不得有重复的视图列名称。
+ 视图必须包含没有默认值的基表中的所有列。
+ 视图列必须是简单的列引用而不是导出列。导出列不是简单的列引用,而是从表达式导出的。下面给出了一些导出列示例:
* 3.14159
* col1 + 3
* UPPER(col2)
* col3 / col4
* (subquery)
mysql> describe v3;+----------------+-------------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+----------------+-------------+------+-----+---------+-------+| user_id | int(11) | NO | | 0 | || nickname | varchar(25) | NO | | | || lhmoney | int(11) | NO | | 0 | || user_recommend | longtext | YES | | NULL | || goods | int(10) | NO | | 0 | |+----------------+-------------+------+-----+---------+-------+
mysql> show table status like 'v3'\G -- 该命令与查看普通表的命令是一样的,而此处大多数为NULL正是证明视图是一张虚表;*************************** 1. row ***************************Name: v3Engine: NULLVersion: NULLRow_format: NULLRows: NULLAvg_row_length: NULLData_length: NULLMax_data_length: NULLIndex_length: NULLData_free: NULLAuto_increment: NULLCreate_time: NULLUpdate_time: NULLCheck_time: NULLCollation: NULLChecksum: NULLCreate_options: NULLComment: VIEW1 row in set (0.01 sec)mysql> show table status like 'users'\G*************************** 1. row ***************************Name: usersEngine: InnoDBVersion: 10Row_format: CompactRows: 171650Avg_row_length: 82Data_length: 14172160Max_data_length: 0Index_length: 11567104Data_free: 66060288Auto_increment: 169781Create_time: 2015-05-01 23:03:29Update_time: NULLCheck_time: NULLCollation: utf8_general_ciChecksum: NULLCreate_options:Comment: 用户信息表1 row in set (0.01 sec)
mysql> show create view v3\G*************************** 1. row ***************************View: v3Create View: CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `u`.`user_id` AS `user_id`,`u`.`nickname` AS `nickname`,`u`.`lhmoney` AS `lhmoney`,`c`.`user_recommend` AS `user_recommend`,`c`.`goods` AS `goods` from (`users` `u` join `comment` `c`on((`u`.`user_id` = `c`.`user_id`))) order by `u`.`user_id` WITH CASCADED CHECK OPTIONcharacter_set_client: utf8collation_connection: utf8_general_ci1 row in set (0.01 sec)
mysql> SELECT * FROM information_schema.views\G*************************** 1. row ***************************TABLE_CATALOG: defTABLE_SCHEMA: testTABLE_NAME: v1VIEW_DEFINITION: select `test`.`users`.`user_id` AS `user_id`,`test`.`users`.`nickname` AS `nickname`,if((`test`.`users`.`sex` = 1),'男','女') AS `sex`,`test`.`users`.`user_money` AS `user_money`from `test`.`users` order by `test`.`users`.`user_money` desc limit 10CHECK_OPTION: NONEIS_UPDATABLE: NODEFINER: root@localhostSECURITY_TYPE: DEFINERCHARACTER_SET_CLIENT: utf8COLLATION_CONNECTION: utf8_general_ci
information_schema是Mysql自带的一个数据库,详细请参考我的另外一边博文《探寻mysql自带的数据库》
大数据分表时可以用到:
比如,表的行数超过200万行时,就会变慢,这时可以把一张的表的数据拆成4张表来存放.
思路1:
News表,分成四表,每表给一个id
Newsid, 1,2,3,4
News1,news2,news3,news4表
把一张表的数据分散到4张表里,分散的方法很多,
最常用可以用id取模来计算.
Id%4+1 = [1,2,3,4]
比如
$_GET['id'] = 17,17%4 + 1 = 2,$tableName = 'news'.'2'Select * from news2 where id = 17;
思路2:
还可以用视图, 把4张表形成一张视图
Create view news as select from n1 union select from n2 union.........