Mysql中的視圖

什麼是視圖

通俗的講,視圖就是一條SELECT語句執行後返回的結果集。因此咱們在建立視圖的時候,主要的工做就落在建立這條SQL查詢語句上。算法

視圖的特性

視圖是對若干張基本表的引用,一張虛表,查詢語句執行的結果,不存儲具體的數據(基本表數據發生了改變,視圖也會跟着改變);數據庫

能夠跟基本表同樣,進行增刪改查操做(ps:增刪改操做有條件限制);安全

視圖的做用

方便操做,特別是查詢操做,減小複雜的SQL語句,加強可讀性;ide

更加安全,數據庫受權命令不能限定到特定行和特定列,可是經過合理建立視圖,能夠把權限限定到行列級別;性能

使用場合

權限控制的時候,不但願用戶訪問表中某些含敏感信息的列,好比salary...spa

關鍵信息來源於多個複雜關聯表,能夠建立視圖提取咱們須要的信息,簡化操做;code

視圖實例1-建立視圖及查詢數據操做

現有三張表:用戶(user)、課程(course)、用戶課程中間表(user_course),表結構及數據以下:blog

表定義:ip

-- ----------------------------
-- Table structure for `course`
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(200) NOT NULL,
  `description` varchar(500) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', 'JAVA', 'JAVA課程');
INSERT INTO `course` VALUES ('2', 'C++', 'C++課程');
INSERT INTO `course` VALUES ('3', 'C語言', 'C語言課程');

-- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `account` varchar(255) NOT NULL,
  `name` varchar(255) NOT NULL,
  `address` varchar(255) DEFAULT NULL,
  `others` varchar(200) DEFAULT NULL,
  `others2` varchar(200) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'user1', '小陳', '美國', '1', '1');
INSERT INTO `user` VALUES ('2', 'user2', '小張', '日本', '2', '2');
INSERT INTO `user` VALUES ('3', 'user3', '小王', '中國', '3', '3');

-- ----------------------------
-- Table structure for `user_course`
-- ----------------------------
DROP TABLE IF EXISTS `user_course`;
CREATE TABLE `user_course` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `userid` bigint(20) NOT NULL,
  `courseid` bigint(20) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user_course
-- ----------------------------
INSERT INTO `user_course` VALUES ('1', '1', '2');
INSERT INTO `user_course` VALUES ('2', '1', '3');
INSERT INTO `user_course` VALUES ('3', '2', '1');
INSERT INTO `user_course` VALUES ('4', '2', '2');
INSERT INTO `user_course` VALUES ('5', '2', '3');
INSERT INTO `user_course` VALUES ('6', '3', '2');
View Code

表數據:權限控制

這時,當咱們想要查詢小張上的因此課程相關信息的時候,須要這樣寫一條長長的SQL語句,以下:

SELECT
    `uc`.`id` AS `id`,
    `u`.`name` AS `username`,
    `c`.`name` AS `coursename`
FROM
    `user` `u`
LEFT JOIN `user_course` `uc` ON ((`u`.`id` = `uc`.`userid`))
LEFT JOIN `course` `c` ON ((`uc`.`courseid` = `c`.`id`))
WHERE
    u.`name` = '小張'

可是咱們能夠經過視圖簡化操做,例如咱們建立視圖view_user_course以下:

-- ----------------------------
-- View structure for `view_user_course`
-- ----------------------------
DROP VIEW
IF EXISTS `view_user_course`;

CREATE ALGORITHM = UNDEFINED 
DEFINER = `root`@`localhost` 
SQL SECURITY DEFINER
VIEW `view_user_course` AS ( SELECT `uc`.`id` AS `id`, `u`.`name` AS `username`, `c`.`name` AS `coursename` FROM ( ( `user` `u` LEFT JOIN `user_course` `uc` ON ((`u`.`id` = `uc`.`userid`)) ) LEFT JOIN `course` `c` ON ((`uc`.`courseid` = `c`.`id`)) ) );

幾點說明(MySQL中的視圖在標準SQL的基礎之上作了擴展):

ALGORITHM=UNDEFINED:指定視圖的處理算法;

DEFINER=`root`@`localhost`:指定視圖建立者;

SQL SECURITY DEFINER:指定視圖查詢數據時的安全驗證方式;

建立好視圖以後,咱們能夠直接用如下SQL語句在視圖上查詢小張上的因此課程相關信息,一樣能夠獲得所需結果:

SELECT
    vuc.username,
    vuc.coursename
FROM
    view_user_course vuc
WHERE
     vuc.username = '小張'

視圖實例2-增刪改數據操做

繼續,咱們能夠嘗試在視圖view_user_course上作增刪改數據操做,以下:

update view_user_course set username='test',coursename='JAVASCRIPT' where id=3

遺憾的是操做失敗,提示錯誤信息以下:

[SQL] update view_user_course set username='test',coursename='JAVASCRIPT' where id=3

[Err] 1393 - Can not modify more than one base table through a join view 'demo.view_user_course'

由於不能在一張由多張關聯錶鏈接而成的視圖上作同時修改兩張表的操做;

那麼哪些操做能夠在視圖上進行呢?

視圖與表是一對一關係狀況:若是沒有其它約束(如視圖中沒有的字段,在基本表中是必填字段狀況),是能夠進行增刪改數據操做;

如咱們建立用戶關鍵信息視圖view_user_keyinfo,以下:

-- ----------------------------
-- View structure for `view_user_keyinfo`
-- ----------------------------
DROP VIEW
IF EXISTS `view_user_keyinfo`;

CREATE ALGORITHM = UNDEFINED DEFINER = `root`@`localhost` SQL SECURITY DEFINER VIEW `view_user_keyinfo` AS SELECT
    `u`.`id` AS `id`,
    `u`.`account` AS `account`,
    `u`.`name` AS `username`
FROM
    `user` `u`;

進行增刪改操做以下,操做成功(注意user表中的其它字段要容許爲空,不然操做失敗):

INSERT INTO view_user_keyinfo (account, username)
VALUES
    ('test1', 'test1');
DELETE
FROM
    view_user_keyinfo
WHERE
    username = 'test1';
UPDATE view_user_keyinfo
SET username = 'updateuser'
WHERE
    id = 1

視圖與表是一對多關係狀況:若是隻修改一張表的數據,且沒有其它約束(如視圖中沒有的字段,在基本表中是必填字段狀況),是能夠進行數據操做,如如下語句,操做成功;

update view_user_course set coursename='JAVA' where id=1;
update view_user_course set username='test2' where id=3;

如下操做失敗:

delete from view_user_course where id=3;
insert into view_user_course(username, coursename) VALUES('2','3');

其它

視圖中的查詢語句性能要調到最優;

修改操做時要當心,不經意間你已經修改了基本表裏的多條數據;

其它性能相關方面待實踐體會...

相關文章
相關標籤/搜索