1. 程式人生 > >MySql基本學習知識點:

MySql基本學習知識點:

master 多表 write update語句 全部 通告 是否為空 char times

1.Mysql的簡介:

(1):常識:

  • MySQL是一種關系數據庫管理系統,是一種開源軟件
  • 由瑞典MySQL AB公司開發,2008年1月16號被Sun公司收購。2009年,SUN又被Oracle收購
  • MySQL軟件采用雙授權政策,分為社區版和商業版。由於體積小、速度快、總體擁有成本低,尤其是開放源碼特點,一般中小型網站的開發都選擇MySQL作為網站數據庫。
  • 由於其社區版的性能卓越,搭配PHP和Apache可組成良好的開發環境。
  • MySQL能夠工作在眾多不同的平臺上

(2):基本安裝信息:

  • 端口:3306
  • 默認用戶:root
  • 字符集:默認字符集latin1,應設置為gbk或utf-8
  • 安裝時可以啟動遠程登錄、創建匿名賬戶
  • 可安裝圖形化操作界面,方便操作

(3):安裝mysql錯誤操作:

·手動刪除mysql安裝目錄

·重新運行配置向導MySQLInstanceConfig.exe

·刪除C:\ProgramData\MySQL目錄

2.Mysql命令:

(1).連接數據庫:

  • 格式: mysql -h主機地址 -u用戶名 -p用戶密碼

    1、連接到本機上的
    MYSQL
  • 進入目錄mysql\bin,再鍵入命令mysql -u root -p,

    2、連接到遠程主機上的MYSQL假設遠程主機的IP為:110.110.110.110,用戶名為root,密碼為abcd123。則鍵入以下命令:
    mysql -h110.110.110.110 -u root -p 123;(註:u與root之間可以不用加空格,其它也一樣)

    3、退出MYSQL命令: exit (回車)
  • 格式:mysqladmin -u用戶名 -p舊密碼 password 新密碼
    1、給root加個密碼ab12
    mysqladmin -u root -password ab12
    註:因為開始時root沒有密碼,所以-p舊密碼一項就可以省略了。
    2、再將root的密碼改為djg345
    mysqladmin -u root -p ab12 password djg345
  • 註意:和上面不同,下面的因為是MYSQL環境中的命令,所以後面都帶一個分號作為命令結束符
    格式:grant select,insert,update,delete on 數據庫.* to 用戶名@登錄主機 identified by “密碼”

    1、增加一個用戶test1密碼為abc,讓他可以在任何主機上登錄,並對所有數據庫有查詢、插入、修改、刪除的權限。首先用root用戶連入MYSQL,然後鍵入以下命令:
    grant select,insert,update,delete on *.* to [email=test1@”%]test1@”%[/email]” Identified by “abc”;
    但增加的用戶是十分危險的,你想如某個人知道test1的密碼,那麽他就可以在internet上的任何一臺電腦上登錄你的mysql數據庫並對你的數據可以為所欲為了,解決辦法見2。
    2、增加一個用戶test2密碼為abc,讓他只可以在localhost上登錄,並可以對數據庫mydb進行查詢、插入、修改、刪除的操作(localhost指本地主機,即MYSQL數據庫所在的那臺主機),這樣用戶即使用知道test2的密碼,他也無法從internet上直接訪問數據庫,只能通過MYSQL主機上的web頁來訪問了。
    grant select,insert,update,delete on mydb.* to [email=test2@localhost]test2@localhost[/email] identified by “abc”;

    如果你不想test2有密碼,可以再打一個命令將密碼消掉。
    grant select,insert,update,delete on mydb.* to [email=test2@localhost]test2@localhost[/email] identified by “”;

(2).修改密碼:

(3).添加新用戶:

(4.1).創建數據庫:

  • 註意:創建數據庫之前要先連接Mysql服務器
    命令:create database <數據庫名>
    1:建立一個名為xhkdb的數據庫
    mysql> create database xhkdb;
    2:創建數據庫並分配用戶
    ①CREATE DATABASE 數據庫名;
    ②GRANT SELECT,INSERT,UPDATE,DELETE,CREATE,DROP,ALTER ON 數據庫名.* TO 數據庫名@localhost IDENTIFIED BY ‘密碼‘;
    ③SET PASSWORD FOR ‘數據庫名‘@‘localhost‘ = OLD_PASSWORD(‘密碼‘);
    依次執行3個命令完成數據庫創建。註意:中文 “密碼”和“數據庫”是戶自己需要設置的。

(4.2).顯示數據庫:

  • 命令:show databases (註意:最後有個s)
    mysql> show databases;

    註意:為了不再顯示的時候亂碼,要修改數據庫默認編碼。以下以GBK編碼頁面為例進行說明:
    1、修改MYSQL的配置文件:my.ini裏面修改default-character-set=gbk
    2、代碼運行時修改:
    ①Java代碼:jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk
    ②PHP代碼:header("Content-Type:text/html;charset=gb2312");
    ③C語言代碼:int mysql_set_character_set( MYSQL * mysql, char * csname);
    該函數用於為當前連接設置默認的字符集。字符串csname指定了1個有效的字符集名稱。連接校對成為字符集的默認校對。該函數的工作方式與SET NAMES語句類似,但它還能設置mysql- > charset的值,從而影響了由mysql_real_escape_string() 設置的字符集。

(4.3).刪除數據庫:

  • 命令:drop database <數據庫名>
    例如:刪除名為 xhkdb的數據庫
    mysql> drop database xhkdb;
    例子1:刪除一個已經確定存在的數據庫
    mysql> drop database drop_database;
    Query OK, 0 rows affected (0.00 sec)
    例子2:刪除一個不確定存在的數據庫
    mysql> drop database drop_database;
    ERROR 1008 (HY000): Can‘t drop database ‘drop_database‘; database doesn‘t exist
    //發生錯誤,不能刪除‘drop_database‘數據庫,該數據庫不存在。
    mysql> drop database if exists drop_database;
    Query OK, 0 rows affected, 1 warning (0.00 sec)//產生一個警告說明此數據庫不存在
    mysql> create database drop_database;
    Query OK, 1 row affected (0.00 sec)
    mysql> drop database if exists drop_database;//if exists 判斷數據庫是否存在,不存在也不產生錯誤
    Query OK, 0 rows affected (0.00 sec)

(4.4).連接數據庫:

  • 命令: use <數據庫名>
    例如:如果xhkdb數據庫存在,嘗試存取它:
    mysql> use xhkdb;
    屏幕提示:Database changed
    use 語句可以通告MySQLdb_name數據庫作為默認(當前)數據庫使用,用於後續語句。該數據庫保持為默認數據庫,直到語段的結尾,或者直到發布一個不同的USE語句:
    mysql> USE db1;
    mysql> SELECT COUNT(*) FROM mytable; # selects from db1.mytable
    mysql> USE db2;
    mysql> SELECT COUNT(*) FROM mytable; # selects from db2.mytable
    使用USE語句為一個特定的當前的數據庫做標記,不會阻礙您訪問其它數據庫中的表。下面的例子可以從db1數據庫訪問作者表,並從db2數據庫訪問編輯表:
    mysql> USE db1;
    mysql> SELECT author_name,editor_name FROM author,db2.editor
    > WHERE author.editor_id = db2.editor.editor_id;
    USE語句被設立出來,用於與Sybase相兼容。
    有些網友問到,連接以後怎麽退出。其實,不用退出來,use 數據庫後,使用show databases就能查詢所有數據庫,如果想跳到其他數據庫,用
    use 其他數據庫名字
    就可以了。

(4.5).當前選擇的數據庫:

  • 命令:mysql> select database();
    MySQL中SELECT命令類似於其他編程語言裏的print或者write,你可以用它來顯示一個字符串、數字、數學表達式的結果等等。如何使用MySQL中SELECT命令的特殊功能?
    1.顯示MYSQL的版本
    mysql> select version();
    +-----------------------+
    | version()|
    +-----------------------+
    | 6.0.4-alpha-community |
    +-----------------------+
    1 row in set (0.02 sec)
  • SELECT DATABASE( ) 當前數據庫名 (或者返回空)
  • SELECT USER( ) 當前用戶名
  • SHOW STATUS服務器狀態
  • SHOW VARIABLES服務器配置變量
    2. 顯示當前時間
    mysql> select now();
    +---------------------+
    | now()|
    +---------------------+
    | 2009-09-15 22:35:32 |
    +---------------------+
    1 row in set (0.04 sec)

    3. 顯示年月日
    SELECT DAYOFMONTH(CURRENT_DATE);
    +--------------------------+
    | DAYOFMONTH(CURRENT_DATE) |
    +--------------------------+
    |15 |
    +--------------------------+
    1 row in set (0.01 sec)

    SELECT MONTH(CURRENT_DATE);
    +---------------------+
    | MONTH(CURRENT_DATE) |
    +---------------------+
    | 9 |
    +---------------------+
    1 row in set (0.00 sec)

    SELECT YEAR(CURRENT_DATE);
    +--------------------+
    | YEAR(CURRENT_DATE) |
    +--------------------+
    | 2009 |
    +--------------------+
    1 row in set (0.00 sec)

    4. 顯示字符串
    mysql> SELECT "welecome to my blog!";
    +----------------------+
    | welecome to my blog! |
    +----------------------+
    | welecome to my blog! |
    +----------------------+
    1 row in set (0.00 sec)

    5. 當計算器用
    select ((4 * 4) / 10 ) + 25;
    +----------------------+
    | ((4 * 4) / 10 ) + 25 |
    +----------------------+
    | 26.60 |
    +----------------------+
    1 row in set (0.00 sec)

    6. 串接字符串
    select CONCAT(f_name, " ", l_name)
    AS Name
    from employee_data
    where title = ‘Marketing Executive‘;
    +---------------+
    | Name |
    +---------------+
    | Monica Sehgal |
    | Hal Simlai |
    | Joseph Irvine |
    +---------------+
    3 rows in set (0.00 sec)
    註意:這裏用到CONCAT()函數,用來把字符串串接起來。另外,我們還用到以前學到的AS給結果列‘CONCAT(f_name, " ", l_name)‘起了個假名。

(5.1).創建數據表:

命令:create table <表名> ( <字段名1> <類型1> [,..<字段名n> <類型n>]);

例如,建立一個名為MyClass的表,

字段名

數字類型

數據寬度

是否為空

是否主鍵

自動增加

默認值

id

int

4

primary key

auto_increment

name

char

20

sex

int

4

0

degree

double

16


  • mysql> create table MyClass(
    > id int(4) not null primary key auto_increment,【主鍵自增】
    > name char(20) not null,
    > sex int(4) not null default ‘0‘,
    > degree double(16,2));

(5.2).刪除數據表:

  • 命令:drop table <表名>
    例如:刪除表名為 MyClass 的表
    mysql> drop table MyClass;
    DROP TABLE用於取消一個或多個表。您必須有每個表的DROP權限。所有的表數據和表定義會被取消,所以使用本語句要小心!
    註意:對於一個帶分區的表,DROP TABLE會永久性地取消表定義,取消各分區,並取消儲存在這些分區中的所有數據。DROP TABLE還會取消與被取消的表有關聯的分區定義(.par)文件。
    對與不存在的表,使用IF EXISTS用於防止錯誤發生。當使用IF EXISTS時,對於每個不存在的表,會生成一個NOTE。
    RESTRICT和CASCADE可以使分區更容易。目前,RESTRICT和CASCADE不起作用。

(5.3).表插入數據:

  • 命令:insert into <表名> [( <字段名1>[,..<字段名n > ])] values ( 值1 )[, ( 值n )]
    例如:往表 MyClass中插入二條記錄, 這二條記錄表示:編號為1的名為Tom的成績為96.45, 編號為2 的名為Joan 的成績為82.99, 編號為3 的名為Wang 的成績為96.5。
    mysql> insert into MyClass values(1,‘Tom‘,96.45),(2,‘Joan‘,82.99), (2,‘Wang‘, 96.59);
    註意:insert into每次只能向表中插入一條記錄。

(5.4).查詢表中的數據:

  • 1)、查詢所有行
    命令: select <字段1,字段2,...> from < 表名 > where < 表達式 >
    例如:查看表 MyClass 中所有數據
    mysql> select * from MyClass;
    2)、查詢前幾行數據
    例如:查看表 MyClass 中前2行數據
    mysql> select * from MyClass order by id limit 0,2;

  • select一般配合where使用,以查詢更精確更復雜的數據。

(5.5).刪除表中的數據:

命令:delete from 表名 where 表達式
例如:刪除表 MyClass中編號為1 的記錄
mysql> delete from MyClass where id=1;

(5.6).修改表中數據:

  • 語法:update 表名 set 字段=新值,… where 條件
    mysql> update MyClass set name=‘Mary‘ where id=1;
    例子1:單表的MySQL UPDATE語句:
    UPDATE [LOW_PRIORITY] [IGNORE] tbl_name SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition] [ORDER BY ...] [LIMIT row_count]
    例子2:多表的UPDATE語句:
    UPDATE [LOW_PRIORITY] [IGNORE] table_references SET col_name1=expr1 [, col_name2=expr2 ...] [WHERE where_definition]
    UPDATE語法可以用新值更新原有表行中的各列。SET子句指示要修改哪些列和要給予哪些值。WHERE子句指定應更新哪些行。如果沒有WHERE子句,則更新所有的行。如果指定了ORDER BY子句,則按照被指定的順序對行進行更新。LIMIT子句用於給定一個限值,限制可以被更新的行的數目。

(5.7).增加字段:

  • 命令:alter table 表名 add字段 類型 其他;
    例如:在表MyClass中添加了一個字段passtest,類型為int(4),默認值為0
    mysql> alter table MyClass add passtest int(4) default ‘0‘
    加索引
    mysql> alter table 表名 add index 索引名 (字段名1[,字段名2 …]);
    例子: mysql> alter table employee add index emp_name (name);
    加主關鍵字的索引
    mysql> alter table 表名 add primary key (字段名);
    例子: mysql> alter table employee add primary key(id);
    加唯一限制條件的索引
    mysql> alter table 表名 add unique 索引名 (字段名);
    例子: mysql> alter table employee add unique emp_name2(cardnumber);
    刪除某個索引
    mysql> alter table 表名 drop index 索引名;
    例子: mysql>alter table employee drop index emp_name;
    增加字段:
    mysql> ALTER TABLE table_name ADD field_name field_type;

    修改原字段名稱及類型:
    mysql> ALTER TABLE table_name CHANGE old_field_name new_field_name field_type;
    刪除字段:
    MySQL> ALTER TABLE table_name DROP field_name;

(5.8).修改表名:

  • 命令:rename table 原表名 to 新表名;
    例如:在表MyClass名字更改為YouClass
    mysql> rename table MyClass to YouClass;
    當你執行 RENAME 時,你不能有任何鎖定的表或活動的事務。你同樣也必須有對原初表的 ALTER 和 DROP 權限,以及對新表的 CREATE 和 INSERT 權限。
    如果在多表更名中,MySQL 遭遇到任何錯誤,它將對所有被更名的表進行倒退更名,將每件事物退回到最初狀態。
    RENAME TABLE 在 MySQL 3.23.23 中被加入。

(6).備份數據庫:

  • 命令在DOS的[url=file://\\mysql\\bin]\\mysql\\bin[/url]目錄下執行
    1.導出整個數據庫
    導出文件默認是存在mysql\bin目錄下
    mysqldump -u 用戶名 -p 數據庫名 > 導出的文件名
    mysqldump -u user_name -p123456 database_name > outfile_name.sql
    2.導出一個表
    mysqldump -u 用戶名 -p 數據庫名 表名> 導出的文件名
    mysqldump -u user_name -p database_name table_name > outfile_name.sql
    3.導出一個數據庫結構
    mysqldump -u user_name -p -d –add-drop-table database_name > outfile_name.sql
    -d 沒有數據 –add-drop-table 在每個create語句之前增加一個drop table
    4.帶語言參數導出
    mysqldump -uroot -p –default-character-set=latin1 –set-charset=gbk –skip-opt database_name > outfile_name.sql
    例如,將aaa庫備份到文件back_aaa中:
    [root@test1 root]# cd /home/data/mysql
    [root@test1 mysql]# mysqldump -u root -p --opt aaa > back_aaa

(7).一個建庫和建表的實例:

  • drop database if exists school; //如果存在SCHOOL則刪除
    create database school; //建立庫SCHOOL
    use school; //打開庫SCHOOL
    create table teacher //建立表TEACHER
    (
    id int(3) auto_increment not null primary key,
    name char(10) not null,
    address varchar(50) default ‘深圳’,
    year date
    ); //建表結束
    //以下為插入字段
    insert into teacher values(”,’allen’,‘大連一中’,‘1976-10-10′);
    insert into teacher values(”,’jack’,‘大連二中’,‘1975-12-23′);
    如果你在mysql提示符鍵入上面的命令也可以,但不方便調試。
    1、你可以將以上命令原樣寫入一個文本文件中,假設為school.sql,然後復制到c:\\下,並在DOS狀態進入目錄[url=file://\\mysql\\bin]\\mysql\\bin[/url],然後鍵入以下命令:
    mysql -uroot -p密碼 < c:\\school.sql
    如果成功,空出一行無任何顯示;如有錯誤,會有提示。(以上命令已經調試,你只要將//的註釋去掉即可使用)。
    2、或者進入命令行後使用 mysql> source c:\\school.sql; 也可以將school.sql文件導入數據庫中。
  • 註:在建表中
    1、將ID設為長度為3的數字字段:int(3);並讓它每個記錄自動加一:auto_increment;並不能為空:not null;而且讓他成為主字段primary key。
    2、將NAME設為長度為10的字符字段
    3、將ADDRESS設為長度50的字符字段,而且缺省值為深圳。
    4、將YEAR設為日期字段。

3.數據類型

· 數值類型:

  • SMALLINT: 2個字節
  • INT: 4個字節 // age int(10)
  • INTEGER:INT的同義詞
  • BIGINT : 8個字節
  • FLOAT : 4個字節
  • DOUBLE : 8個字節 //score float(10,2)
  • 字符串(字符)類型
    • CHAR:固定長度字符串 sex char(2)
    • VARCHAR:可變長度字符串 name varchar(20)
    • VARCHAR使用起來較為靈活,CHAR處理速度更快
    • TEXT:非二進制大對象(字符)
    • BLOB:二進制大對象(非字符)
  • 日期/時間類型:
    • DATE: YYYY-MM-DD
    • DATETIME: YYYY-MM-DD HH:MM:SS
    • TIMESTAMP: YYYY-MM-DD HH:MM:SS
    • TIME:HH:MM:SS
    • YEAR:YYYY
  • 主鍵自增
    • 不使用序列,通過auto_increment

4.SQL語句語法:

  • SQL語言包含4個部分:
    • 數據定義語言(如create,drop,alter等語句)
    • 數據查詢語言(select語句)
    • 數據操縱語言(insert,delete,update語句)
    • 數據控制語言(如grant,revoke,commit,rollback等語句)

數據操縱語言針對表中的數據,而數據定義語言針對數據庫或表

  • 數據定義語言

create database school; /*創建數據庫*/

show databases; /*顯示所有數據庫select database()*/

use school; /*指定默認數據庫*/

create table student( /*創建表*/

id int(10) primary key auto_increment, /*主鍵,自增*/

name varchar(8),

sex char(1),

score float(6,2)

);

show tables; /*顯示當前庫中表清單*/

/* 顯示指定表結構show columns from student;*/

describe student;

show create table student; /*顯示建表sql語句*/

drop table student; /*刪除表*/

drop database school; /*刪除數據庫*/

  • 數據操縱語言

insert into student values("張三", "t",87.5);

insert into student values(null,"張三","t",87.5);

//insert into student (name,sex,score) values("張三","t",87.5);

select * from student;

insert into student values(null,"李四","男",89);

alter table student modify sex char(2);

insert into student values(null,"李四","男",89);

select * from student;

update student set sex ="女";

select * from student;

update student set sex="男" where id=1;

select * from student;

update student set name="王五" ,score=100 where id=2;

select * from student;

delete from student where name="王五";

select * from student;

delete from student;

select * from student;

  • 數據查詢語言(select語句)
    • select * from student;
    • select id,name,score from student;
    • select * from student where id<5 and sex=“男”;
    • select count(*) from student ;
    • select max(score) from student;
    • select id ,name,score from student order by score desc;
    • select * from stu where name like "張%";

  • 更改表結構語句
    • alter table student add birth date;
    • insert into student values(null,"趙六","男",100, now() );
    • insert into student values(null,"趙六","男",100, “1980-12-23");
    • alter table student change birth birthday date ;
    • alter table student modify sex char(4) not null ;
    • alter table student modify sex char(2) after birthday;
    • alter table student rename as stu;

alter table stu drop birthday;

  • 多表查詢和外鍵關聯

create table person( id int primary key, name varchar(6), sex char(2), age int(10) );

insert into person values(1,"張三","男",45);

insert into person values(2,"李四","男",32);

insert into person values(3,"王五","女",32);

create table pet(

id int auto_increment ,

name varchar(6),

masterid int,

primary key(id),

constraint fk foreign key (masterid) references person(id)

);

  • 分頁語句
    • select * from table limit (start-1)*limit,limit;
    • 其中start是頁碼

limit是每頁顯示的條數.

5.導入導出:

  • 命令行操作
    • 導入
      • 方法1:mysql>source d:\dbname.sql
      • 方法2:mysql -u root -p 數據庫名 < dbname.sql
      • 導出
        • 導出整個數據庫
          • mysqldump -u root -p 數據庫名 > dbname.sql
          • 只導出一個表
            • mysqldump -u root -p 數據庫名 表名> dbname.sql
  • 圖形界面操作
    • Navicat
    • 導入:運行SQL文件
    • 導出:轉儲SQL文件

6.mysql數據庫的內連接與外連接的區別:

內連接指的是把表連接時表與表之間匹配的數據行查詢出來,就是兩張表之間數據行匹配時,要同時滿足ON語句後面的條件才行。

左連接的意思是,無論是否符合ON語句後面的表連接條件都會把左邊那張表的記錄全部查詢出來,右邊的那張表只匹配符合條件的數據行。右連接則與之相反(這裏同樣OUTER 可以省略

7.MySql的事務處理:

MySQL 事務

MySQL 事務主要用於處理操作量大,復雜度高的數據。比如說,在人員管理系統中,你刪除一個人員,你即需要刪除人員的基本資料,也要刪除和該人員相關的信息,如信箱,文章等等,這樣,這些數據庫操作語句就構成一個事務!

  • 在 MySQL 中只有使用了 Innodb 數據庫引擎的數據庫或表才支持事務。
  • 事務處理可以用來維護數據庫的完整性,保證成批的 SQL 語句要麽全部執行,要麽全部不執行。
  • 事務用來管理 insert,update,delete 語句

一般來說,事務是必須滿足4個條件(ACID)::原子性(Atomicity,或稱不可分割性)、一致性(Consistency)、隔離性(Isolation,又稱獨立性)、持久性(Durability)。

  • 原子性:一個事務(transaction)中的所有操作,要麽全部完成,要麽全部不完成,不會結束在中間某個環節。事務在執行過程中發生錯誤,會被回滾(Rollback)到事務開始前的狀態,就像這個事務從來沒有執行過一樣。
  • 一致性:在事務開始之前和事務結束以後,數據庫的完整性沒有被破壞。這表示寫入的資料必須完全符合所有的預設規則,這包含資料的精確度、串聯性以及後續數據庫可以自發性地完成預定的工作。
  • 隔離性:數據庫允許多個並發事務同時對其數據進行讀寫和修改的能力,隔離性可以防止多個事務並發執行時由於交叉執行而導致數據的不一致。事務隔離分為不同級別,包括讀未提交(Read uncommitted)、讀提交(read committed)、可重復讀(repeatable read)和串行化(Serializable)。
  • 持久性:事務處理結束後,對數據的修改就是永久的,即便系統故障也不會丟失。

在 MySQL 命令行的默認設置下,事務都是自動提交的,即執行 SQL 語句後就會馬上執行 COMMIT 操作。因此要顯式地開啟一個事務務須使用命令 BEGIN 或 START TRANSACTION,或者執行命令 SET AUTOCOMMIT=0,用來禁止使用當前會話的自動提交。

事務控制語句:

  • BEGIN 或 START TRANSACTION 顯式地開啟一個事務;
  • COMMIT 也可以使用 COMMIT WORK,不過二者是等價的。COMMIT 會提交事務,並使已對數據庫進行的所有修改成為永久性的;
  • ROLLBACK 也可以使用 ROLLBACK WORK,不過二者是等價的。回滾會結束用戶的事務,並撤銷正在進行的所有未提交的修改;
  • SAVEPOINT identifier,SAVEPOINT 允許在事務中創建一個保存點,一個事務中可以有多個 SAVEPOINT;
  • RELEASE SAVEPOINT identifier 刪除一個事務的保存點,當沒有指定的保存點時,執行該語句會拋出一個異常;
  • ROLLBACK TO identifier 把事務回滾到標記點;
  • SET TRANSACTION 用來設置事務的隔離級別。InnoDB 存儲引擎提供事務的隔離級別有READ U NCOMMITTED、READ COMMITTED、REPEATABLE READ 和 SERIALIZABLE。

MYSQL 事務處理主要有兩種方法:

1、用 BEGIN, ROLLBACK, COMMIT來實現

  • BEGIN 開始一個事務
  • ROLLBACK 事務回滾
  • COMMIT 事務確認

2、直接用 SET 來改變 MySQL 的自動提交模式:

  • SET AUTOCOMMIT=0 禁止自動提交
  • SET AUTOCOMMIT=1 開啟自動提交

數據庫事務隔離級別

數據庫事務的隔離級別有4個,由低到高依次為Read uncommitted 、Read committed 、Repeatable read 、Serializable ,這四個級別可以逐個解決臟讀 、不可重復讀 、幻讀 這幾類問題。

√: 可能出現 ×: 不會出現

臟讀

不可重復讀

幻讀

Read uncommitted

Read committed

×

Repeatable read

×

×

Serializable

×

×

×

註意:我們討論隔離級別的場景,主要是在多個事務並發 的情況下,因此,接下來的講解都圍繞事務並發。

Read uncommitted 讀未提交

公司發工資了,領導把5000元打到singo的賬號上,但是該事務並未提交,而singo正好去查看賬戶,發現工資已經到賬,是5000元整,非常高 興。可是不幸的是,領導發現發給singo的工資金額不對,是2000元,於是迅速回滾了事務,修改金額後,將事務提交,最後singo實際的工資只有 2000元,singo空歡喜一場。

出現上述情況,即我們所說的臟讀 ,兩個並發的事務,“事務A:領導給singo發工資”、“事務B:singo查詢工資賬戶”,事務B讀取了事務A尚未提交的數據。

當隔離級別設置為Read uncommitted 時,就可能出現臟讀,如何避免臟讀,請看下一個隔離級別。

Read committed 讀提交

singo拿著工資卡去消費,系統讀取到卡裏確實有2000元,而此時她的老婆也正好在網上轉賬,把singo工資卡的2000元轉到另一賬戶,並在 singo之前提交了事務,當singo扣款時,系統檢查到singo的工資卡已經沒有錢,扣款失敗,singo十分納悶,明明卡裏有錢,為 何......

出現上述情況,即我們所說的不可重復讀 ,兩個並發的事務,“事務A:singo消費”、“事務B:singo的老婆網上轉賬”,事務A事先讀取了數據,事務B緊接了更新了數據,並提交了事務,而事務A再次讀取該數據時,數據已經發生了改變。

當隔離級別設置為Read committed 時,避免了臟讀,但是可能會造成不可重復讀。

大多數數據庫的默認級別就是Read committed,比如Sql Server , Oracle。如何解決不可重復讀這一問題,請看下一個隔離級別。

Repeatable read 重復讀

當隔離級別設置為Repeatable read 時,可以避免不可重復讀。當singo拿著工資卡去消費時,一旦系統開始讀取工資卡信息(即事務開始),singo的老婆就不可能對該記錄進行修改,也就是singo的老婆不能在此時轉賬。

雖然Repeatable read避免了不可重復讀,但還有可能出現幻讀 。

singo的老婆工作在銀行部門,她時常通過銀行內部系統查看singo的信用卡消費記錄。有一天,她正在查詢到singo當月信用卡的總消費金額 (select sum(amount) from transaction where month = 本月)為80元,而singo此時正好在外面胡吃海塞後在收銀臺買單,消費1000元,即新增了一條1000元的消費記錄(insert transaction ... ),並提交了事務,隨後singo的老婆將singo當月信用卡消費的明細打印到A4紙上,卻發現消費總額為1080元,singo的老婆很詫異,以為出 現了幻覺,幻讀就這樣產生了。

註:MySQL的默認隔離級別就是Repeatable read。

Serializable 序列化

Serializable 是最高的事務隔離級別,同時代價也花費最高,性能很低,一般很少使用,在該級別下,事務順序執行,不僅可以避免臟讀、不可重復讀,還避免了幻像讀。



二、臟讀、幻讀、不可重復讀

1.臟讀:
臟讀就是指當一個事務正在訪問數據,並且對數據進行了修改,而這種修改還沒有提交到數據庫中,這時,另外一個事務也訪問這個數據,然後使用了這個數據。


2.不可重復讀:
是指在一個事務內,多次讀同一數據。在這個事務還沒有結束時,另外一個事務也訪問該同一數據。那麽,在第一個事務中的兩次讀數據之間,由於第二個事務的修改,那麽第一個事務兩次讀到的的數據可能是不一樣的。這樣就發生了在一個事務內兩次讀到的數據是不一樣的,因此稱為是不可重復讀。(即不能讀到相同的數據內容)
例如,一個編輯人員兩次讀取同一文檔,但在兩次讀取之間,作者重寫了該文檔。當編輯人員第二次讀取文檔時,文檔已更改。原始讀取不可重復。如果只有在作者全部完成編寫後編輯人員才可以讀取文檔,則可以避免該問題。


3.幻讀:
是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麽,以後就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象
發生了幻覺一樣。
例如,一個編輯人員更改作者提交的文檔,但當生產部門將其更改內容合並到該文檔的主復本時,發現作者已將未編輯的新材料添加到該文檔中。如果在編輯人員和生產部門完成對原始文檔的處理之前,任何人都不能將新材料添加到文檔中,則可以避免該問題。

8.MySql數據庫索引:

  • 一、簡介
  • MySQL目前主要有以下幾種索引類型:
    1.普通索引
    2.唯一索引
    3.主鍵索引
    4.組合索引
    5.全文索引
  • 二、語句
  • CREATE TABLE table_name[col_name data type]
  • [unique|fulltext][index|key][index_name](col_name[length])[asc|desc]
  • 1.unique|fulltext為可選參數,分別表示唯一索引、全文索引
    2.index和key為同義詞,兩者作用相同,用來指定創建索引
    3.col_name為需要創建索引的字段列,該列必須從數據表中該定義的多個列中選擇
    4.index_name指定索引的名稱,為可選參數,如果不指定,默認col_name為索引值
    5.length為可選參數,表示索引的長度,只有字符串類型的字段才能指定索引長度
    6.asc或desc指定升序或降序的索引值存儲
  • (三)使用索引的優點
  • 1.可以通過建立唯一索引或者主鍵索引,保證數據庫表中每一行數據的唯一性.
    2.建立索引可以大大提高檢索的數據,以及減少表的檢索行數
    3.在表連接的連接條件 可以加速表與表直接的相連
    4.在分組和排序字句進行數據檢索,可以減少查詢時間中 分組 和 排序時所消耗的時間(數據庫的記錄會重新排序)
    5.建立索引,在查詢中使用索引 可以提高性能
  • (四)使用索引的缺點
  • 1.在創建索引和維護索引 會耗費時間,隨著數據量的增加而增加
    2.索引文件會占用物理空間,除了數據表需要占用物理空間之外,每一個索引還會占用一定的物理空間
    3.當對表的數據進行 INSERT,UPDATE,DELETE 的時候,索引也要動態的維護,這樣就會降低數據的維護速度,(建立索引會占用磁盤空間的索引文件。一般情況這個問題不太嚴重,但如果你在一個大表上創建了多種組合索引,索引文件的會膨脹很快)。
  • (五)使用索引需要註意的地方
  • 在建立索引的時候應該考慮索引應該建立在數據庫表中的某些列上面 哪一些索引需要建立,哪一些所以是多余的.
    一般來說,
    1.在經常需要搜索的列上,可以加快索引的速度
    2.主鍵列上可以確保列的唯一性
    3.在表與表的而連接條件上加上索引,可以加快連接查詢的速度
    4.在經常需要排序(order by),分組(group by)和的distinct 列上加索引 可以加快排序查詢的時間, (單獨order by 用不了索引,索引考慮加where 或加limit)
    5.在一些where 之後的 < <= > >= BETWEEN IN 以及某個情況下的like 建立字段的索引(B-TREE)
  • 6.like語句的 如果你對nickname字段建立了一個索引.當查詢的時候的語句是 nickname lick ‘%ABC%‘ 那麽這個索引講不會起到作用.而nickname lick ‘ABC%‘ 那麽將可以用到索引
  • 7.索引不會包含NULL列,如果列中包含NULL值都將不會被包含在索引中,復合索引中如果有一列含有NULL值那麽這個組合索引都將失效,一般需要給默認值0或者 ‘ ‘字符串
  • 8.使用短索引,如果你的一個字段是Char(32)或者int(32),在創建索引的時候指定前綴長度 比如前10個字符 (前提是多數值是唯一的..)那麽短索引可以提高查詢速度,並且可以減少磁盤的空間,也可以減少I/0操作.
  • 9.不要在列上進行運算,這樣會使得mysql索引失效,也會進行全表掃描
  • 10.選擇越小的數據類型越好,因為通常越小的數據類型通常在磁盤,內存,cpu,緩存中 占用的空間很少,處理起來更快
  • (六)什麽情況下不創建索引
  • 1.查詢中很少使用到的列 不應該創建索引,如果建立了索引然而還會降低mysql的性能和增大了空間需求.
    2.很少數據的列也不應該建立索引,比如 一個性別字段 0或者1,在查詢中,結果集的數據占了表中數據行的比例比較大,mysql需要掃描的行數很多,增加索引,並不能提高效率
    3.定義為text和image和bit數據類型的列不應該增加索引,
    4.當表的修改(UPDATE,INSERT,DELETE)操作遠遠大於檢索(SELECT)操作時不應該創建索引,這兩個操作是互斥的關系

9.MySql註入:

所謂SQL註入,就是通過把SQL命令插入到Web表單遞交或輸入域名或頁面請求的查詢字符串,最終達到欺騙服務器執行惡意的SQL命令。

我們永遠不要信任用戶的輸入,我們必須認定用戶輸入的數據都是不安全的,我們都需要對用戶輸入的數據進行過濾處理。

防止SQL註入,我們需要註意以下幾個要點:

1.永遠不要信任用戶的輸入。對用戶的輸入進行校驗,可以通過正則表達式,或限制長度;對單引號和 雙"-"進行轉換等。

2.永遠不要使用動態拼裝sql,可以使用參數化的sql或者直接使用存儲過程進行數據查詢存取。

3.永遠不要使用管理員權限的數據庫連接,為每個應用使用單獨的權限有限的數據庫連接。

4.不要把機密信息直接存放,加密或者hash掉密碼和敏感的信息。

5.應用的異常信息應該給出盡可能少的提示,最好使用自定義的錯誤信息對原始錯誤信息進行包裝

6.sql註入的檢測方法一般采取輔助軟件或網站平臺來檢測,軟件一般采用sql註入檢測工具jsky,網站平臺就有億思網站安全平臺檢測工具。MDCSOFT SCAN等。采用MDCSOFT-IPS可以有效的防禦SQL註入,XSS攻擊等。

應對方法:

1.mysql_escape_string() 轉義特殊字符((PHP 4 >= 4.3.0, PHP 5))(mysql_real_escape_string必須先鏈接上數據庫,否則會報錯)

下列字符受影響:

\x00 //對應於ascii字符的NULL

\n //換行符且回到下一行的最前端

\r //換行符

\ //轉義符

"

\x1a //16進制數

如果成功,則該函數返回被轉義的字符串。如果失敗,則返回 false。

2.addslashes(): 函數返回在預定義字符之前添加反斜杠的字符串 (stripslashes()實現字符串還原)

預定義的字符有:

單引號(‘)

雙引號(")

反斜杠(\)

NULL

3.prepared statements(預處理機制)

MySql基本學習知識點: