Chinaunix首页 | 论坛 | 博客
  • 博客访问: 303847
  • 博文数量: 58
  • 博客积分: 2763
  • 博客等级: 少校
  • 技术积分: 731
  • 用 户 组: 普通用户
  • 注册时间: 2008-09-04 19:07
文章分类

全部博文(58)

文章存档

2011年(55)

2009年(1)

2008年(2)

分类: LINUX

2011-09-04 11:26:14


视图:实际是一张虚表,是存储下来的select语句。
 
创建视图:
            CREATE VIEW view_name AS SELECT 条件
mysql> CREATE VIEW myview AS SELECT ID,Uname,Uage,CourseID FROM user WHERE CourseID IS NOT NULL;
只要基表改变,视图就会改变。
例如:
mysql> select * from myview;
+----+-----------+------+----------+
| ID | Uname     | Uage | CourseID |
+----+-----------+------+----------+
|  1 | Yang Guo  |   25 |        2 |
|  2 | xiao feng |   35 |        4 |
|  3 | Duan Yu   |   20 |        9 |
|  4 | Xu Zhu    |   22 |       10 |
+----+-----------+------+----------+
4 rows in set (0.02 sec)
           
如果你不想使用视图了,想要删除视图,使用下面的命令:
       DROP VIEW view_name
------------------------------------------------------
子查询:  换言之就是嵌套查询,把查询的结果当作条件。
例如:查询年龄大于平均年龄的人的姓名和年龄
             SELECT Uname,Uage FROM user WHERE Uage > (SELECT AVG(Uage) FROM user WHERE Uage IS NOT NULL);
             平均年龄:
mysql> SELECT AVG(Uage) FROM user WHERE Uage IS NOT NULL;
+-----------+
| AVG(Uage) |
+-----------+
|   24.5714 |
+-----------+
1 row in set (0.00 sec)
 
mysql> SELECT Uname,Uage FROM user WHERE Uage > (SELECT AVG(Uage) FROM user WHERE Uage IS NOT NULL);
+-------------+------+
| Uname       | Uage |
+-------------+------+
| Yang Guo    |   25 |
| xiao feng   |   35 |
| Hong xigong |   70 |
+-------------+------+
3 rows in set (0.00 sec)
---------------------------------------

事务:Transact
事务:要么同时都做了,要么同时都没做。这么说你可能不好理解,我就哪一个例子来说明吧。你拿着10元钱去买练习本,练习本的价格是2元,你给老板10元,老板给你一个本,并给你8元。整个事件就是一个事务。
应用到数据库中就是说所做的查询语句要么都执行,要么都不执行。

引擎:MyISAM 不支持事务
      InnoDB 支持事务
     
判断一个引擎是否支持事务:
判断标准:ACID
A:Atomicity 原子性
C:Consistency 一致性(结构的一致)
I:Isolation 隔离性(多个事务之间彼此互相影响的关系)
D:Durability 持久性 完成后的结果要永久保存下来


隔离性:MySQL的隔离级别跟存储引擎相关
MySQL的隔离级别:
        读未提交:READ UNCOMMITED,最低级别
        读提交:READ COMMITED
        可重读的:REPEATABLE READ(MySQL默认级别)
        串行化:SERIABLIZABLE

       
级别越高,事物的安全性越好,并发性越差。
事务在提交之前可以回退,使用rollback;

查看默认级别
mysql> SHOW VARIABLES LIKE 'tx_isolation';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| tx_isolation  | REPEATABLE-READ |
+---------------+-----------------+
1 row in set (0.00 sec)

--------------------
例如有两个事务A和B

读未提交:A和B同时开始,例如A插入一条数据,并未提交,此时B使用查询会看到A插入的结构。

读提交:A和B同事开始,例如A插入一条数据,并未提交,此时B使用查询看不到A所插入的数据,只有当A执行COMMIT命令之后,B使用查询才能看到,插入的数据。

可重读:A和B同事开始,例如A插入一条数据,并未提交,此时B使用查询看不到A所插入的数据,即使当A执行COMMIT命令之后,B使用查询任然看不到A所插入的数据,直到B也执行COMMIT命令之后,再用查询命令才能看到插入的数据。

串行化:只有当A的整个事务完成以后,B再开始执行

MVCC:多版本并发控制(A和B的操作互不影响)
-----------------------------------------
查看表的存储引擎:
SHOW TABLE status\G;

开始事务:
START TRANSACTION;
回退:
ROLLBACK;
提交:
COMMIT
-----------------------------------------
mysql> START TRANSACTION
mysql> SELECT * FROM user;
mysql> INSERT INTO user SET Uname='shizhongyu';

回退:
mysql> ROLLBACK;

明确显示提交:
mysql> COMMIT;
提交过之后,回退就不起作用了

上面有提到过查看默认事务级别,也可以使用下面命令:
SELECT @@SESSION.tx_isolation;

修改事务级别:
    修改为读未提交

SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

    设置为默认级别:
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

---------------------------------------------------------
开启两台虚拟机,分别启动mysqld服务

第一个:
START TRANSACTION
DELETE FROM user WHERE UID=10;
COMMIT;


第二个:只有自己提交之后,才会更新
SATRT TRANSACTION;
COMMIT;
----------------------------------
锁:对同一个表进行操作时,只要一个人的操作开始了,另一个人的操作会被限制。

读锁:又称为共享锁,因为不同用户可以同时使用SELECT查询

写锁:又称为独占锁,只有当一个用户操作完毕,释放了锁,另一个用户才能执行操作。

写锁的优先级比较高

那就会有人会问,我们什么时候才能用到所能?对数据库的数据进行备份,此时就需要加锁。

锁级别
表锁:对表进行加锁,别的用户无法对此表作任何操作。
行锁:并发级别高,可控制性复杂,其他行任然可以查询。
页锁
page,页锁,通常指内存空间

手动加锁:
LOCK TABLES table_name 锁类型
        加读锁
       LOCK TABLES user READ;
        释放锁
        UNLOCK TABLES;
------------------------
存储引擎:             锁级别
MyISAM/Merge  :       Table
InnoDB                 Row
MEMORY ,保存在内存中。提供类似内存数据库 ,通常默认是16M                  Table
Maria                  Row
Falcom                 Row
PBXT                   Row
FEDERATED  仅仅是联合两个表的
NDB                    Row
Archive  归档存储引擎,做数据挖掘        Row
Blackhole  作为中继日志的转发节点           
CSV  存储成文本文件    Table
------------------------------------------------
MyISAM:
每一个表都对应3个数据文件。
.frm  表格的保存文件
.MYD  数据的保存文件
.MYI  索引的保存文件

MyISAM的特性:
    非事务
    不支持外键
    全文索引
    无数据缓存
    对索引进行缓存
    支持HASH和BTREE索引
    表级别的锁
    读性能非常好(数据仓库)
    可以压缩存放
    温备
    最大支持64个索引。

服务器变量:(调整MyISAM性能)
        key_buffer_size,调整索引缓存大小,无论你是什么引擎,该项必须得有
                    SHOW VARIABLES LIKE 'key_buffer_size';
        
       concurent_insert ,并发写入
     
       delay_key_write ,延迟键的写入操作,不是马上就修改索引值。
            查看该值: 
            SELECT @@GLOABL.delay_key_write
     
       max_write_lock_count
     
       preload_buffer_size ,用于指定key 缓存
     
MyISAM的管理工具:
        myisamchk 分析,修复,优化
        myisampack 压缩
        myisam_ftdump 显示全文索引
       
----------------------
InnoDB
        特性:    基于MVCC,支持事务
                  行级别锁
                  支持外键
                  聚簇索引,索引和数据在一块放。
                  索引缓存和数据缓存,
                  热备(依靠备份工具)
          使用表空间,把表都放在同一个空间。默认表空间名ibdata1  ,表空间文件可以有多个。                  innodb_data_home_dir 数据文件所在目录
          默认存放在你定义的datadir中       
                    innodb_data_file_path 文件路径
                    innodb_buffer_pool_size ,能够同时缓存数据和索引
                    innodb_log_file_size 日志文件,128-256M
                    innodb_flush_log_at_trx_commit 多长时间同步到磁盘上。默认是1 。
                   
           查看INNODB存储引擎信息:
                    SHOW ENGINE INNODB STATUS\G;
注意:如果你是二进制编译的话,直接对/etc/my.cnf进行修改。
      如果你是使用rpm包装的话,你可以使用rpm -ql mysql-server来查看一下。其中有一行为/usr/share/doc/mysql-server-5.0.77/my-medium.cnf,修改完之后,复制到/etc/my.cnf。      

练习3:
1、为mytb表创建视图records,要求只保留显示ID、zone、host、type、Mx_priority和data字段;
mysql> CREATE VIEW records AS SELECT ID,zone,host,type,Mx_priority,data from www;
练习4:
1、改变mytb的存储引擎为innodb;
mysql> ALTER TABLE www ENGINE=InnoDB;
2、设置mysql的事务隔离级别为READ COMMITED;同时显式启动两个事务A和B,以A事务向mytb中删除一行,查看B事务是否觉察到此改变;而后A事务提交后再使用B事务查看是否能看到相应的改变,而后提交B事务;
mysql> SHOW VARIABLES LIKE 'tx%';
mysql> SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;
A:mysql> DELETE FROM www WHERE ID=1663822;
B:SELECT * FROM www LIMIT 10;
没有变化;
A:COMMIT;
B: SELECT * FROM www LIMIT 10;
变化;
B: COMMIT;
3、启动两个mysql客户端M和N;在M上对mytb启动显式读锁,并执行一个SELECT语句;接着在N上往mytb中插入一个新行;而后在M客户端释放施加的读锁;
M:
mysql> LOCK TABLES www READ;
mysql> select * from www LIMIT 10;

N:
mysql> INSERT INTO www (host) VALUES ('www');
会插入不进去
当在M上执行了UNLOCK TABLES;之后,就可以插入成功了。

练习5:
如果你是二进制编译的话,直接对/etc/my.cnf进行修改。
如果你是使用rpm包装的话,你可以使用rpm -ql mysql-server来查看一下。
其中有一行为/usr/share/doc/mysql-server-5.0.77/my-medium.cnf
在配置文件中修改

1、设定mysql的innodb的数据目录为/innodata,并设定其文件为ibdata01和ibdata02,其中ibdata01初始大小为1024M,不能自动增长;ibdata02初始大小为50M,可以自动增长;

innodb_data_home_dir = /innodata
innodb_data_file_path = ibdata01:1024M;ibdata02:50M:autoextend

2、设定mysql的innodb的日志文件组目录为/innolog(提示:通过innodb_log_group_home_dir设定),日志组中共有4个日志文件(innodb_log_files_in_group),每个日志文件大小为50M;

innodb_log_group_home_dir = /innolog
innodb_log_files_in_group = 4
innodb_log_file_size = 50M

3、设置innodb日志和数据缓冲的大小为128M;

innodb_log_buffer_size = 128M

-------------------------------------------------------------

用户管理:

mysql用户的授权信息表:
user,db,host,tables_priv,columns_priv,procs_priv
这六张表主要指定权限委派的。

用户账号:有两段组成
'username'@'HOST'
password中的值是加密存储的。

-----------------------------------
授权格式:
 
GRANT
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type]
        {
            *
          | *.*
          | db_name.*
          | db_name.tbl_name
          | tbl_name
          | db_name.routine_name

        }
    TO user [IDENTIFIED BY [PASSWORD] 'password']
        [, user [IDENTIFIED BY [PASSWORD] 'password']] ...
    [REQUIRE
        NONE |
        [{SSL| X509}]
        [CIPHER 'cipher' [AND]]
        [ISSUER 'issuer' [AND]]
        [SUBJECT 'subject']]
    [WITH with_option [with_option] ...]

object_type =
    TABLE
  | FUNCTION
  | PROCEDURE

with_option =
    GRANT OPTION
  | MAX_QUERIES_PER_HOUR count
  | MAX_UPDATES_PER_HOUR count
  | MAX_CONNECTIONS_PER_HOUR count
  | MAX_USER_CONNECTIONS count
------------------------------------

tables_priv:对表的操作权限
columns_priv:更为细微的权限定义,对字段的操作权限
procs_priv:定义用户是否有存储过程权限的。

有哪些权限可以进行授权呢?
DML:SELECT,INSERT,UPDATE,DELETE
DDL:CREATE,DROP,
INDEX:
ALTER:定义用户修改表结构的权限
SHOW DATABASE;
SUPER:管理命令的权限
LOCK TABLES;
CREATE VIEW,SHOW VIEW:
CREATE USER(包含删除用户)
REPLICATION SLAVE(此用户是否具有从主服务器上复制二进制日志内容的权限)
REPLICATION CLIENT(表示请求主从环境当中用于复制的相关信息的权限,是否具有在主从复制架构当中,获得主服务器和从服务器架构当中信息的权限)
GRANT OPTION (此用户是否可以给别的用户授予权限)

----------------------
创建用户账号
CREATE USER user_name@'主机' IDENTIFIED BY 'password'
此时用户没有任何权限(USAGE权限仅能连接到数据库和SHOW DATABASES;)。

>CREATE USER tom@'%' IDENTIFIED BY 'redhat';
>FLUSH PRIVILEGES;

% 匹配任意长度的任意字符
_ 匹配任意单个字符

192.168.0.%
192.168.0.0/255.255.255.0

对象类型:
        TABLE
        FUNCTION
        PROCEDURE


想要使tom有创建数据库和表的权限
GRANT CREATE ON hello.* TO 'tom'@'%';
--------------------------------
查看用户所拥有的权限
SHOW GRANTS FOR 'root'@'localhost';

GRANT DROP ON hello.* TO 'tom' @'%';

添加的权限会在原有权限上累加

GRANT SELECT ON hello.* TO 'tom' @'%';

撤销授权:
格式:
REVOKE
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type]
        {
            *
          | *.*
          | db_name.*
          | db_name.tbl_name
          | tbl_name
          | db_name.routine_name

        }
    FROM user [, user] ...


REVOKE SELECT ON hellodb.* FROM 'tom'@'%';
FLUSH PRIVILEGES;

----------------------------------------
总结一下:
创建用户
CREATE USER username@host [IDENTIFIED BY 'password'];

删除用户
DROP USER username@host;

授权
GRANT priv_list ON db.table TO username@host [IDENTIFIED BY 'password'];

撤销权限
REVOKE priv_list ON db.table FROM username@host;

WITH GRANT OPTION
(把自己的权限给别人)

限定其所使用的资源;

WITH MAX_QUERIES_PER_HOUR n;只能发起有限次查询;
WITH MAX_UPDATEs_PER_HOUR n;每个小时只能修改几次
WITH MAX_COMMENTIONS_PER_HOUR n;每个小时只能连接几次
WITH MAX_USER_CONNECTIONS n;同一个用户在同一时间能够连进来几次

FLUSH USER_RESOURCES;  重读限定用户资源的定义

---------------------------------------------

字段级别的权限:
限定用户在某个特定字段具有某种权限:
GRANT SELECT(name) ON db.table TO username@host;

执行存储过程和存储函数的权限:
GRANT EXECUTE ON [FUNCTION|PROCEDURE] TO username@host;

如果mysql的root用户密码忘记了:
恢复管理员密码
1.停止服务
(1)如果你是使用rpm包安装的mysql,则
ls /usr/bin/mysql* (其中有mysqld_safe文件)
#/usr/bin/mysqld_safe --skip-grant-tables --skip-networking &

(2)如果你是使用绿色安装(二进制安装),则
ls /usr/local/mysql/bin
#/usr/local/mysql/bin/mysqld_safe --skip-grant-tables --skip-networking &


2.设定密码:
        #mysql
        >use mysql;
        >UPDATE user SET password=PASSWORD('redhat') WHERE User='root' AND HOST='localhost';

3.退出,并重新正常启动mysql。


练习6:
按要求创建如下用户:
1、用户rpel,只能通过172.16.0.0/24内的主机访问,密码同用户名;而后授予其在数据库上执行REPLICATION CLIENT和REPLICATION SLAVE的权限;
mysql> show grants for rpel@'172.16.0.%';
mysql> GRANT REPLICATION CLIENT ON *.* TO rpel@'172.16.0.%';
mysql> GRANT REPLICATION SLAVE ON *.* TO rpel@'172.16.0.%';

2、用户vikram,具有在testdb数据库上执行创建和删除tb_test表的权限;
   mysql> CREATE USER vikram@'%' IDENTIFIED BY 'redhat';
   mysql> GRANT CREATE ON testdb.* TO vikram@'%';
   mysql> GRANT DROP ON testdb.* TO vikram@'%';
   mysql> FLUSH PRIVILEGES;
   在另一台主机上:mysql -uvikram -p -h192.168.0.75
   mysql> CREATE TABLE tb_test(
    -> tbuser VARCHAR(20),
    -> tb*** ENUM ('F','M') NOT NULL DEFAULT 'M',
    -> tbage int(5) NOT NULL);
    mysql> DROP TABLE tb_test;
   mysql> REVOKE CREATE,DROP ON testdb.* FROM vikram@'%';
  
3、用户gentoo,具有在mytb表中查询Host字段中数据的权限;此用户账号只能同时连入服务器1次;
  CREATE USER gentoo@'%' IDENTIFIED BY 'redhat';
  GRANT SELECT(Host) ON mydb.www TO gentoo@'%' WITH MAX_CONNENTIONS_PER_HOUR 1 ;
  FLUSH USER_RESOURCES;
  #service mysqld restart
  在另一台主机上:
    mysql -ugentoo -p -h192.168.0.75
4、用户centos,具有在mytb表中查询、插入和修改数据的权限;此用户每小时只能发起50次修改操作;
  mysql> CREATE USER centos@'%' IDENTIFIED BY 'redhat';
  mysql> GRANT SELECT,INSERT,UPDATE ON mydb.www TO centos@'%' WITH MAX_UPDATES_PER_HOUR 50;
  FLUSH USER_RESOURCES;

阅读(1857) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~