1. Mysql 支持的数据类型
数据类型是定义列中可以存储什么数据以及该数据实际怎样存储的基本规则。
数据类型用于以下目的:
- 口数据类型允许限制可存储在列中的数据。例如,数值数据类型列只能接受数值。
- 口数据类型允许在内部更有效地存储数据。可以用一种比文本串更简洁的格式存储数值和日期时间值。
- 口数据类型允许变换排序顺序。如果所有数据都作为串处理,则1位于10之前,而10又位于2之前(串以字典顺序排序,从左边开始比较,一次一个字径)。作为数值数据类型,数值才能正确排序。
在设计表时,应该特别重视所用的数据类型。使用错误的数据类型可能会严重地影响应用程序的功能和性能。更改包含数据的列不是一件小事(而且这样做可能会导致数据丢失)。
1.1 串数据类型
最常用的数据类型是串数据类型。它们存储串,如名字、地址、电话号码、邮政编码等。有两种基本的串类型,分别为定长串和变长串(参见表D-1).
定长串接受长度固定的字符串,其长度是在创建表时指定的。例如,名字列可允许30个字符,而社会安全号列允许11个字符(允许的字符数目中包括两个破折号),定长列不允许多于指定的字符数目。它们分配的存储空间与指定的一样多。因此,如果串Ben存储到30个字符的名字字段,则存储的是30个字符,CHAR属于定长串类型。
变长串在储可变长度的文本 有些变长数据类型具有最大的定长,而有些则是完全变长的。不管是哪种,只有指定的数据得到保存(额外的数据不保存)TEXT属于变长串类型。
既然变长数据类型这样灵活,为什么还要使用定长数据类型?回答是因为性能,MySOL处理定长列远比处理变长列快得多。此外,MySQL不允许对变长列(或一个列的可变部分)进行索引。这也会极大地影响性能。
使用引号 不管使用何种形式的串数据类型,串值都必须括在引号内(通常单引号更好).
当数值不是数值时 你可能会认为电话号码和邮政编码应该存储在數值字段中(数值字段只存储数值数据),但是,这样做却是不可取的。如果在数值字段中存储邮政编码01234,則保存的将是數值1234,实际上丢失了一位数字.
需要遵守的基本规则是:如果数值是计算(求和、平均等)中使用的数值,则应该存储在数值数据类型列中,如果作为字符串(可能只包含数字)使用,则应该保存在串数据类型列中
1.2 数值数据类型
数值数据类型存储数值. MySQL支持多种数值数据类型,每种存储的数值具有不同的取值范围。显然,支持的取值范围越大,所需存储空间越多。此外,有的数值数据类型支持使用十进制小数点(和小数),而1有的则只支持整数。表D-2列出了常用的MySQL数值数据类型。
有符号或无符号
所有数值数据类型(除BIT和BOOLEAN外)都可以有符号或无符号,有符号数值列可以存储正或负的数值,无符号数值列只能存储正数,默认情况为有符号,但如果你知道自己不需要存储负值,可以使用UNSIGNED关键字,这样做将允许你存储两倍大小的值.
不使用引号 与串不一样,数值不应该括在引号内。
存储货币数据类型 MySQL中没有专门存储货币的数据类型,一般情况下使用DECIMAL(8,2)
1.3 日期和时间数据类型
MySQL使用专门的数据类型来存储日期和时间值
1.4 二进制数据类型
二进制数据类型可存储任何数据(甚至包括二进制信息),如图像、多媒体、字处理文档等(参见表D-4).
2. 创建和操纵表
处理现有的表 在创建新表时,指定的表名必须不存在,否则将出错,如果要防止意外覆盖已有的表,SQL要求首先手工册除该表,然后再重建它,而不是简单地用创建表语句覆盖它.
如果你仅想在一个表不存在时创建它,应该在表名后给出IF NOT EXISTS.这样做不检查已有表的模式是否与你打算创建的表模式相匹配。它只是查看表名是否存在,并且仅在表名不存在时创建它
理解NULL 不要把NULL值与空串相混淆.NULL值是没有值它不是空串。如果指定 ''(两个单引号,其间没有字符),这在NOT NULL列中是允许的,空串是一个有效的值,它不是无值. NULL值用关键字NULL而不是空串指定。
主键值必须唯一。即,表中的每个行必须具有唯一的主键值。如果主键使用单个列,则它的值必须唯一。如果使用多个列,则这些列的组合值必须唯一。
mysql> show create table orderitems;
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| orderitems | CREATE TABLE `orderitems` (
`order_num` int(11) NOT NULL,
`order_item` int(11) NOT NULL,
`prod_id` char(10) NOT NULL,
`quantity` int(11) NOT NULL,
`item_price` decimal(8,2) NOT NULL,
PRIMARY KEY (`order_num`,`order_item`),
KEY `fk_orderitems_products` (`prod_id`),
CONSTRAINT `fk_orderitems_orders` FOREIGN KEY (`order_num`) REFERENCES `orders` (`order_num`),
CONSTRAINT `fk_orderitems_products` FOREIGN KEY (`prod_id`) REFERENCES `products` (`prod_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 |
+------------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.01 sec)
主键可以在创建表时定义(如这里所示),或者在创建表之后定义。
主键和NULL值 主键为其值唯一标识表中每个行的列,主键中只能使用不允许NULL值的列.允许NULL值的列不能作为唯一标识。
每个表只允许一个AUTO INCREMENT列,而且它必须被索引(如,通过使它成为主键)。
覆盖AUTO-INCREMENT 如果一个列被指定为AUTO-INCRE MENT,则它需要使用特殊的值吗?你可以简单地在INSERT语句中指定一个值,只要它是唯一的(至A尚未使用t)即可,该值将被用来替代自动生成的值,后续的增量将开始使用该手工插入的值。
mysql> select * from book;
+----+------------------+-----------+-------+--------+
| id | name | author | price | status |
+----+------------------+-----------+-------+--------+
| 11 | 水浒传 | 施耐庵 | 10 | 0 |
| 12 | 白发魔女传 | 梁羽生 | 10 | 0 |
| 13 | 倚天屠龙记 | 金庸 | 10 | 1 |
| 16 | 白发魔女传2 | 梁羽生 | 10 | 0 |
| 17 | 白发魔女传3 | 梁羽生 | 10 | 1 |
| 19 | 倚天屠龙记2 | 金庸 | 10 | 0 |
| 20 | 倚天屠龙记3 | 金庸 | 10 | 0 |
| 21 | 倚天屠龙记4 | 金庸 | 15 | 0 |
| 22 | 倚天屠龙记5 | 金庸 | 10 | 1 |
| 23 | 天龙八部 | 金庸 | 10 | 0 |
+----+------------------+-----------+-------+--------+
10 rows in set (0.01 sec)
mysql> insert into book values(28,"笑傲江湖","金庸",20,0);
Query OK, 1 row affected (0.01 sec)
mysql> select * from book;
+----+------------------+-----------+-------+--------+
| id | name | author | price | status |
+----+------------------+-----------+-------+--------+
| 11 | 水浒传 | 施耐庵 | 10 | 0 |
| 12 | 白发魔女传 | 梁羽生 | 10 | 0 |
| 13 | 倚天屠龙记 | 金庸 | 10 | 1 |
| 16 | 白发魔女传2 | 梁羽生 | 10 | 0 |
| 17 | 白发魔女传3 | 梁羽生 | 10 | 1 |
| 19 | 倚天屠龙记2 | 金庸 | 10 | 0 |
| 20 | 倚天屠龙记3 | 金庸 | 10 | 0 |
| 21 | 倚天屠龙记4 | 金庸 | 15 | 0 |
| 22 | 倚天屠龙记5 | 金庸 | 10 | 1 |
| 23 | 天龙八部 | 金庸 | 10 | 0 |
| 28 | 笑傲江湖 | 金庸 | 20 | 0 |
+----+------------------+-----------+-------+--------+
11 rows in set (0.00 sec)
mysql> insert into book(name,author,price,status) values("笑傲江湖2","金庸",20,0);
Query OK, 1 row affected (0.00 sec)
mysql> select * from book;
+----+------------------+-----------+-------+--------+
| id | name | author | price | status |
+----+------------------+-----------+-------+--------+
| 11 | 水浒传 | 施耐庵 | 10 | 0 |
| 12 | 白发魔女传 | 梁羽生 | 10 | 0 |
| 13 | 倚天屠龙记 | 金庸 | 10 | 1 |
| 16 | 白发魔女传2 | 梁羽生 | 10 | 0 |
| 17 | 白发魔女传3 | 梁羽生 | 10 | 1 |
| 19 | 倚天屠龙记2 | 金庸 | 10 | 0 |
| 20 | 倚天屠龙记3 | 金庸 | 10 | 0 |
| 21 | 倚天屠龙记4 | 金庸 | 15 | 0 |
| 22 | 倚天屠龙记5 | 金庸 | 10 | 1 |
| 23 | 天龙八部 | 金庸 | 10 | 0 |
| 28 | 笑傲江湖 | 金庸 | 20 | 0 |
| 29 | 笑傲江湖2 | 金庸 | 20 | 0 |
+----+------------------+-----------+-------+--------+
12 rows in set (0.00 sec)
确定AUTO_INCREMENT值
如何在使用AUTO_INCREMENT列时获得这个值呢?可使用last_insert_id() 函数获得这个值,如下所示:SELECT last_insert_id()
此语句返回最后一个AUTO INCREMENT值,然后可以将它用于后续的MySQL语句.
指定默认值
mysql> show create table book;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| book | CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`author` varchar(255) DEFAULT NULL,
`price` varchar(255) DEFAULT NULL,
`status` int(11) DEFAULT '0',
PRIMARY KEY (`id`),
UNIQUE KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
使用默认值而不是NULL值 许多数据库开发人员使用默认值而不是NULL列,特别是对用于计算或数据分组的列更是如此。
引擎类型
与其他DBMS一样,MySQL有一个具体管理和处理数据的内部引擎。
在你使用CREATE TABLE语句时,该引擎具体创建表,而在你使用SELECT语句或进行其他数据库处理时,该引擎在内部处理你的请求。多数时候,此引擎都隐藏在DBMS内,不需要过多关注它。
但MySQL与其他DBMS不一样,它具有多种引擎。它打包多个引擎,这些引攀都隐藏在MySQL服务器内,全都能执行CREATE TABLE和SELECT等命令。
为什么要发行多种引擎呢?因为它们具有各自不同的功能和特性,为不同的任务选择正确的引擎能获得良好的功能和灵活性
当然,你完全可以忽略这些数据库引擎。如果省略ENGINE-语句,则使用默认引擎(InnoDB),多数SQL语句都会默认使用它。但并不是所有语句都默认使用它,这就是为什么ENGINE-语句很重要的原因(也就是为什么本书的样列表中使用两种引擎的原因)。
以下是几个需要知道的引擎:
- InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索;
- MEMORY功能等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适合于临时表);
- MyISAM是一个性能极高的引擎,它支持全文本搜索,但不支持事务处理。
mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
9 rows in set (0.00 sec)
//默认引擎
mysql> show variables like '%storage_engine%';
+----------------------------+--------+
| Variable_name | Value |
+----------------------------+--------+
| default_storage_engine | InnoDB |
| default_tmp_storage_engine | InnoDB |
| storage_engine | InnoDB |
+----------------------------+--------+
3 rows in set (0.00 sec)
引擎类型可以混用。除productnotes表使用MyISAM外,样例表都使用InnoDB,原因是希望支持事务处理(因此,使用InnoDB),但也需要在productnotes中支持全文本搜索(因此,使用MyISAM).
外键不能跨引擎 混用引擎类型有一个大缺陷,外键(用于强制实施引用完整性)不能跨引擎,即使用一个引擎的表不能引用具有使用不同引擎的表的外键
更新表
为更新表定义,可使用ALTER TABLE语句
mysql> alter table book add type char(20);
Query OK, 0 rows affected (0.05 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from book;
+----+------------------+-----------+-------+--------+------+
| id | name | author | price | status | type |
+----+------------------+-----------+-------+--------+------+
| 11 | 水浒传 | 施耐庵 | 10 | 0 | NULL |
| 12 | 白发魔女传 | 梁羽生 | 10 | 0 | NULL |
| 13 | 倚天屠龙记 | 金庸 | 10 | 1 | NULL |
| 16 | 白发魔女传2 | 梁羽生 | 10 | 0 | NULL |
| 17 | 白发魔女传3 | 梁羽生 | 10 | 1 | NULL |
| 19 | 倚天屠龙记2 | 金庸 | 10 | 0 | NULL |
| 20 | 倚天屠龙记3 | 金庸 | 10 | 0 | NULL |
| 21 | 倚天屠龙记4 | 金庸 | 15 | 0 | NULL |
| 22 | 倚天屠龙记5 | 金庸 | 10 | 1 | NULL |
| 23 | 天龙八部 | 金庸 | 10 | 0 | NULL |
| 28 | 笑傲江湖 | 金庸 | 20 | 0 | NULL |
| 29 | 笑傲江湖2 | 金庸 | 20 | 0 | NULL |
+----+------------------+-----------+-------+--------+------+
12 rows in set (0.00 sec)
mysql> update book set type="武侠小说";
Query OK, 12 rows affected (0.01 sec)
Rows matched: 12 Changed: 12 Warnings: 0
mysql> select * from book;
+----+------------------+-----------+-------+--------+--------------+
| id | name | author | price | status | type |
+----+------------------+-----------+-------+--------+--------------+
| 11 | 水浒传 | 施耐庵 | 10 | 0 | 武侠小说 |
| 12 | 白发魔女传 | 梁羽生 | 10 | 0 | 武侠小说 |
| 13 | 倚天屠龙记 | 金庸 | 10 | 1 | 武侠小说 |
| 16 | 白发魔女传2 | 梁羽生 | 10 | 0 | 武侠小说 |
| 17 | 白发魔女传3 | 梁羽生 | 10 | 1 | 武侠小说 |
| 19 | 倚天屠龙记2 | 金庸 | 10 | 0 | 武侠小说 |
| 20 | 倚天屠龙记3 | 金庸 | 10 | 0 | 武侠小说 |
| 21 | 倚天屠龙记4 | 金庸 | 15 | 0 | 武侠小说 |
| 22 | 倚天屠龙记5 | 金庸 | 10 | 1 | 武侠小说 |
| 23 | 天龙八部 | 金庸 | 10 | 0 | 武侠小说 |
| 28 | 笑傲江湖 | 金庸 | 20 | 0 | 武侠小说 |
| 29 | 笑傲江湖2 | 金庸 | 20 | 0 | 武侠小说 |
+----+------------------+-----------+-------+--------+--------------+
12 rows in set (0.00 sec)
mysql> alter table book drop column type;
Query OK, 0 rows affected (0.03 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> select * from book;
+----+------------------+-----------+-------+--------+
| id | name | author | price | status |
+----+------------------+-----------+-------+--------+
| 11 | 水浒传 | 施耐庵 | 10 | 0 |
| 12 | 白发魔女传 | 梁羽生 | 10 | 0 |
| 13 | 倚天屠龙记 | 金庸 | 10 | 1 |
| 16 | 白发魔女传2 | 梁羽生 | 10 | 0 |
| 17 | 白发魔女传3 | 梁羽生 | 10 | 1 |
| 19 | 倚天屠龙记2 | 金庸 | 10 | 0 |
| 20 | 倚天屠龙记3 | 金庸 | 10 | 0 |
| 21 | 倚天屠龙记4 | 金庸 | 15 | 0 |
| 22 | 倚天屠龙记5 | 金庸 | 10 | 1 |
| 23 | 天龙八部 | 金庸 | 10 | 0 |
| 28 | 笑傲江湖 | 金庸 | 20 | 0 |
| 29 | 笑傲江湖2 | 金庸 | 20 | 0 |
+----+------------------+-----------+-------+--------+
12 rows in set (0.00 sec)
删除表 重命名表
drop table customers2;
rename table customers2 to customers;
3. 使用视图
视图是虚拟的表。与包含数据的表不一样,视图只包含使用时动态检索数据的查询。
3.1 为什么使用视图
- 重用SQL语句
- 简化复杂的SQL操作。在编写查询后,可以方便地重用它而不必知道它的基本查询细节。
- 使用表的组成部分而不是整个表。
- 保护数据。可以给用户授予表的特定部分的访问权限而不是整个表的访问权限。
- 更改数据格式和表示。视图可返回与底层表的表示和格式不同的数据。
在视图创建之后,可以用与表基本相同的方式利用它们。可以对视图执行SELECT操作,过滤和排序数据,将视图联结到其他视图或表,甚至能添加和更新数据(添加和更新数据存在某些限制)
重要的是知道视图仅仅是用来查看存储在别处的数据的一种设施。视图本身不包含数据,因此它们返回的数据是从其他表中检索出来的。在添加或更改这些表中的数据时,视图将返回改变过的数据。
性能问题 因为视图不包含数据,所以每次使用视图时,都必须处理查询执行时所需的任一个检索,如果你用多个联结和过滤创建了复杂的视图或者嵌套了视图,可能会发现性能下降得很厉害,因此,在部署使用了大量视图的应用前,应该进行测试。
3.2 视图的规则和限制
-
与表一样,视图必须唯一命名(不能给视图取与别的视图或表相同的名字)
-
对于可以创建的视图数目没有限制。
-
为了创建视图,必须具有足够的访问权限。这些限制通常由数据库管理人员授予。
-
视图可以嵌套,即可以利用从其他视图中检索数据的查询来构造一个视图。
-
ORDER BY可以用在视图中,但如果从该视图检索数据SELECT中也含有ORDER BY,那么该视图中的ORDER BY将被覆盖。
-
视图不能索引,也不能有关联的触发器或默认值。
-
视图可以和表一起使用。例如,编写一条联结表和视图的SELECT语句。
3.3 使用视图
- 视图用CREATE VIEW语句来创建。
- 使用SHOW CREATE VIEW viewname:来查看创建视图的语句。
- 用DROP删除视图,其语法为DROP VIEW viewname;.
- 更新视图时,可以先DROP再用CREATE,可以直接用CREATE OR REPLACE VIEW.如果要更新的视图不存在,则第2条更新语句会创建一个视图;如果要更新的视图存在,则第2条更新语句会替换原有视图。
//1.使用视图简化复杂的联结
//视图极大地简化了复杂SQL语句的使用。利用视图,可一次性编写基础的SQL,然后根据需要多次便用。
mysql> create view prodcust as
-> select cust_name,cust_contact,prod_id
-> from customers,orders,orderitems
-> where customers.cust_id=orders.cust_id
-> and orders.order_num=orderitems.order_num;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from prodcust;
+----------------+--------------+---------+
| cust_name | cust_contact | prod_id |
+----------------+--------------+---------+
| Coyote Inc. | Y Lee | ANV01 |
| Coyote Inc. | Y Lee | ANV02 |
| Coyote Inc. | Y Lee | TNT2 |
| Coyote Inc. | Y Lee | FB |
| Coyote Inc. | Y Lee | FB |
| Coyote Inc. | Y Lee | OL1 |
| Coyote Inc. | Y Lee | SLING |
| Coyote Inc. | Y Lee | ANV03 |
| Wascals | Jim Jones | JP2000 |
| Yosemite Place | Y Sam | TNT2 |
| E Fudd | E Fudd | FC |
+----------------+--------------+---------+
11 rows in set (0.01 sec)
mysql> select * from prodcust where prod_id='TNT2';
+----------------+--------------+---------+
| cust_name | cust_contact | prod_id |
+----------------+--------------+---------+
| Coyote Inc. | Y Lee | TNT2 |
| Yosemite Place | Y Sam | TNT2 |
+----------------+--------------+---------+
2 rows in set (0.00 sec)
//2.用视图重新格式化检索出的数据
mysql> select concat(RTrim(vend_name),'(',RTrim(vend_country),')')
-> as vend_title
-> from vendors
-> order by vend_name;
+------------------------+
| vend_title |
+------------------------+
| ACME(USA) |
| Anvils R Us(USA) |
| Furball Inc.(USA) |
| Jet Set(England) |
| Jouets Et Ours(France) |
| LT Supplies(USA) |
+------------------------+
6 rows in set (0.00 sec)
//3.用视图过滤不想要的数据 排除没有邮件地址的用户
mysql> create view custemail as
-> select cust_id,cust_name,cust_email
-> from customers
-> where cust_email is not null;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from custemail;
+---------+----------------+---------------------+
| cust_id | cust_name | cust_email |
+---------+----------------+---------------------+
| 10001 | Coyote Inc. | ylee@coyote.com |
| 10003 | Wascals | rabbit@wascally.com |
| 10004 | Yosemite Place | sam@yosemite.com |
| 10008 | cc | cc@1234.com |
| 10009 | dd | dd@1234.com |
| 10010 | ee | ee@1234.com |
| 10011 | eeeee | eeeee@1234.com |
| 10013 | ee | ee@1234.com |
+---------+----------------+---------------------+
8 rows in set (0.00 sec)
//WHERE子句与WHERE子句 如果从视图检索数据时使用了一条WHERE子句,
//则两组子句(一组在视图中,另一组是传递视图的)将自动组合
mysql> select * from custemail where cust_id=10001;
+---------+-------------+-----------------+
| cust_id | cust_name | cust_email |
+---------+-------------+-----------------+
| 10001 | Coyote Inc. | ylee@coyote.com |
+---------+-------------+-----------------+
1 row in set (0.00 sec)
//4.使用视图与计算字段
mysql> create view oe as
-> select order_num,prod_id,quantity,item_price,quantity*item_price as expanded_price
-> from orderitems;
Query OK, 0 rows affected (0.01 sec)
mysql> select * from oe where order_num=20005;
+-----------+---------+----------+------------+----------------+
| order_num | prod_id | quantity | item_price | expanded_price |
+-----------+---------+----------+------------+----------------+
| 20005 | ANV01 | 10 | 5.99 | 59.90 |
| 20005 | ANV02 | 3 | 9.99 | 29.97 |
| 20005 | TNT2 | 5 | 10.00 | 50.00 |
| 20005 | FB | 1 | 10.00 | 10.00 |
+-----------+---------+----------+------------+----------------+
4 rows in set (0.00 sec)
更新视图
迄今为止的所有视图都是和SELECT语句使用的。然而,视图的数据能否更新?答案视情况而定。
通常,视图是可更新的(即,可以对它们用INSERT,UPDATE和DELETE),更新一个视图将更新其基表(可以回忆一下,视图本身没有数据)。如果你对视图增加或删除行,实际上是对其基表增加或删除行。
但是,并非所有视图都是可更新的。基本上可以说,如果MySQL不能正确地确定被更新的基数据,则不允许更新(包括插入和删除)。
将视图用于检索 一般,应该将视图用于检索(SELECT语句)而不用于更新(INSERT,UPDATE和DELETE)
视图提供了一种MySQL的SELECT语句层次的封装,可用来简化数据处理以及重新格式化基础数据或保护基础数据。