QueryCache(下面簡稱QC)是根據SQL語句來cache的。一個SQL查詢如果以select開頭,那么MySQL服務器將嘗試對其使用QC。每個Cache都是以SQL文本作為key來存的。在應用QC之前,SQL文本不會被作任何處理。也就是說,兩個SQL語句,只要相差哪怕是一個字 符(例如大小寫不一樣;多一個空格等),那么這兩個SQL將使用不同的一個CACHE。
不過SQL文本有可能會被客戶端做一些處理。例如在官方的命令行客戶端里,在發送SQL給服務器之前,會做如下處理:
過濾所有注釋,去掉SQL文本前后的空格,TAB等字符。注意,是文本前面和后面的。中間的不會被去掉。
下面的三條SQL里,因為SELECT大小寫的關系,最后一條和其他兩條在QC里肯定是用的不一樣的存儲位置。而第一條和第二條,區別在于后者有個注釋, 在不同客戶端,會有不一樣的結果。所以,保險起見,請盡量不要使用動態的注釋。在PHP的mysql擴展里,SQL的注釋是不會被去掉的。也就是三條SQL會被存儲在三個不同的緩存里,雖然它們的結果都是一樣的。
select * FROM people where name='surfchen';
select * FROM people where /*hey~*/name='surfchen';
SELECT * FROM people where name='surfchen';
目前只有select語句會被cache,其他類似show,use的語句則不會被cache。
因為QC是如此前端,如此簡單的一個緩存系統,所以如果一個表被更新,那么和這個表相關的SQL的所有QC都會被失效。假設一個聯合查詢里涉及到了表A和表B,如果表A或者表B的其中一個被更新(update或者delete),這個查詢的QC將會失效。
也就是說,如果一個表被頻繁更新,那么就要考慮清楚究竟是否應該對相關的一些SQL進行QC了。一個被頻繁更新的表如果被應用了QC,可能會加重數據庫的負擔,而不是減輕負擔。我一般的做法是默認打開QC,而對一些涉及頻繁更新的表的SQL語句加上SQL_NO_CACHE關鍵詞來對其禁用CACHE。這樣可以盡可能避免不必要的內存操作,盡可能保持內存的連續性。
那些查詢很分散的SQL語句,也不應該使用QC。例如用來查詢用戶和密碼的語句——“select pass from user where name='surfchen'”。這樣的語句,在一個系統里,很有可能只在一個用戶登陸的時候被使用。每個用戶的登陸所用到的查詢,都是不一樣的SQL 文本,QC在這里就幾乎不起作用了,因為緩存的數據幾乎是不會被用到的,它們只會在內存里占地方。
存儲塊,在本節里“存儲塊”和“block”是同一個意思。
QC緩存一個查詢結果的時候,一般情況下不是一次性地分配足夠多的內存來緩存結果的。而是在查詢結果獲得的過程中,逐塊存儲。當一個存儲塊被填滿之后,一個新的存儲塊將會被創建,并分配內存(allocate)。單個存儲塊的內存分配大小通過query_cache_min_res_unit參數控制,默認為4KB。最后一個存儲塊,如果不能被全部利用,那么沒使用的內存將會被釋放。如果被緩存的結果很大,那么可能會導致分配內存操作太頻繁,系統性能也隨之下降;而如果被緩存的結果都很小,那么可能會導致內存碎片過多,這些碎片如果太小,就很有可能不能再被分配使用。
除了查詢結果需要存儲塊之外,每個SQL文本也需要一個存儲塊,而涉及到的表也需要一個存儲塊(表的存儲塊是所有線程共享的,每個表只需要一個存儲塊)。 存儲塊總數量=查詢結果數量*2+涉及的數據庫表數量。也就是說,第一個緩存生成的時候,至少需要三個存儲塊:表信息存儲塊,SQL文本存儲塊,查詢結果存儲塊。而第二個查詢如果用的是同一個表,那么最少只需要兩個存儲塊:SQL文本存儲塊,查詢結果存儲塊。
通過觀察Qcache_queries_in_cache和Qcache_total_blocks可以知道平均每個緩存結果占用的存儲塊。它們的比例如果接近1:2,則說明當前的query_cache_min_res_unit參數已經足夠大了。如果Qcache_total_blocks比Qcache_queries_in_cache多很多,則需要增加query_cache_min_res_unit的大小。
Qcache_queries_in_cache * query_cache_min_res_unit(sql文本和表信息所在的block占用的內存很小,可以忽略)如果遠遠大于query_cache_size - Qcache_free_memory,那么可以嘗試減小 query_cache_min_res_unit的值。
調整大小
如果Qcache_lowmem_prunes增長迅速,意味著很多緩存因為內存不夠而被釋放,而不是因為相關表被更新。嘗試加大query_cache_size,盡量使Qcache_lowmem_prunes零增長。
啟動參數
show variables like 'query_cache%' 可以看到這些信息。
query_cache_limit: 如果單個查詢結果大于這個值,則不Cache
query_cache_size: 分配給QC的內存。如果設為0,則相當于禁用QC。要注意QC必須使用大約40KB來存儲它的結構,如果設定小于 40KB,則相當于禁用QC。QC存儲的最小單位是1024 byte,所以如果你設定了一個不是1024的倍數的值,這個值會被四舍五入到最接近當前值的等于1024的倍數的值。
query_cache_type: 0 完全禁止QC,不受SQL語句控制(另外可能要注意的是,即使這里禁用,上面一個參數所設定的內存大小還是會被分配);1啟用QC,可以在SQL語句使用 SQL_NO_CACHE禁用;2可以在SQL語句使用SQL_CACHE啟用。
query_cache_min_res_unit: 每次給QC結果分配內存的大小
狀態
show status like 'Qcache%' 可以看到這些信息。
Qcache_free_blocks: 當一個表被更新之后,和它相關的cache blocks將被free。但是這個block依然可能存在隊列中,除非是在隊列的尾部。這些blocks將會被統計到這個值來。可以用FLUSH QUERY CACHE語句來清空free blocks。
Qcache_free_memory: 可用內存,如果很小,考慮增加query_cache_size
Qcache_hits: 自mysql進程啟動起,cache的命中數量
Qcache_inserts: 自mysql進程啟動起,被增加進QC的數量
Qcache_lowmem_prunes: 由于內存過少而導致QC被刪除的條數。加大query_cache_size,盡可能保持這個值0增長。
Qcache_not_cached: 自mysql進程啟動起,沒有被cache的只讀查詢數量(包括select,show,use,desc等)
Qcache_queries_in_cache: 當前被cache的SQL數量
Qcache_total_blocks: 在QC中的blocks數。一個query可能被多個blocks存儲,而這幾個blocks中的最后一個未用滿的內存將會被釋放掉。例如一個QC結果要占6KB內存,如果query_cache_min_res_unit是4KB,則最后將會生成3個blocks,第一個block用來存儲sql語句文本,這個不會被統計到query_cache_size里,第二個block為4KB,第三個block為2KB(先allocate4KB,然后釋放多余的2KB)。每個表,當第一個和它有關的SQL查詢被CACHE的時候,會使用一個 block來存儲表信息。也就是說,block會被用在三處地方:表信息,SQL文本,查詢結果。
show global status like 'Com_select' 可以看到未中cache的查詢次數,包括讀寫查詢。
SELECT查詢的總數量等價于:
Com_select + Qcache_hits + queries with errors found by parser
Com_select的值等價于:
Qcache_inserts + Qcache_not_cached + queries with errors found during columns/rights check
常用計算公式:
Qcache命中率:Qcache_hits / (Com_select + Qcache_hits)
Qcache碎片率:Qcache_free_blocks / Qcache_total_blocks
Query結果集平均大小:(query_cache_size - Qcache_free_memory) / Qcache_queries_in_cache
在MySQL存儲過程的語句中有三個標準的循環方式:WHILE循環,LOOP循環以及REPEAT循環。還有一種非標準的循環方式:GOTO,不過這種循環方式最好別用,很容易引起程序的混亂,在這里就不錯具體介紹了。
這幾個循環語句的格式如下:
WHILE……DO……END WHILE
REPEAT……UNTIL END REPEAT
LOOP……END LOOP
GOTO。
mysql> create procedure pro10()
Query OK, 0 rows affected (0.00 sec)
mysql> delete from t1//
Query OK, 0 rows affected (0.00 sec)
mysql> call pro10()//
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1//
+——-+
| filed |
+——-+
|
|
|
|
|
+——-+
5 rows in set (0.00 sec)
mysql> create procedure pro11()
Query OK, 0 rows affected (0.00 sec)
mysql> delete from t1//
Query OK, 5 rows affected (0.00 sec)
mysql> call pro11()//
Query OK, 1 row affected (0.00 sec) #雖然在這里顯示只有一行數據受到影響,但是下面選擇數據的話,還是插入了5行數據。
mysql> select * from t1//
+——-+
| filed |
+——-+
|
|
|
|
|
+——-+
5 rows in set (0.00 sec)
一行就是執行結果,實際的作用和使用while編寫的存儲過程一樣,都是插入5行數據。
再來看一下第三個循環控制語句LOOP……END LOOP。編寫一個存儲過程程序如下:
mysql> create procedure pro12()
Query OK, 0 rows affected (0.00 sec)
從上面這個例子可以看出,使用LOOP編寫同樣的循環控制語句要比使用while和repeat編寫的要復雜一些:在循環內部加入了IF……END IF語句,在IF語句中又加入了LEAVE語句,LEAVE語句的意思是離開循環,LEAVE的格式是:LEAVE 循環標號。
mysql> delete from t1//
Query OK, 5 rows affected (0.00 sec)
mysql> call pro12//
Query OK, 1 row affected (0.00 sec) #雖然說只有一行數據受影響,但是實際上是插入了5行數據。
mysql> select * from t1//
+——-+
| filed |
+——-+
|
|
|
|
|
+——-+
5 rows in set (0.00 sec)
mysql> create procedure pro13()
Query OK, 0 rows affected (0.00 sec)
mysql> create procedure pro14()
Query OK, 0 rows affected (0.00 sec)
ITERATE 迭代
mysql> create procedure pro15()
Query OK, 0 rows affected (0.00 sec)
mysql> delete from t1//
Query OK, 5 rows affected (0.00 sec)
mysql> call pro15//
Query OK, 1 row affected (0.00 sec)
mysql> select * from t1//
+——-+
| filed |
+——-+
|
|
|
|
+——-+
4 rows in set (0.00 sec)
和我們上面分析的結果一樣,只插入了數值0,1,2,4。
一、配置文件的修改
1.#sudo vim /etc/mysql/my.cnf
找到 bind-address = 127.0.0.1
注釋掉這句話
二、Mysql數據庫的修改
1) [root@etc etc]# mysql -u root -p
Enter password:
2)mysql> use mysql;
3)mysql> select host,user,password from user;
4)grant all privileges on *.* to root@192.168.15.101 identified by 'password'
注意: (1)192.168.15.101是欲連接到此Mysql數據庫的客戶端的IP地址,而不是Mysql數據庫所在數據庫服務器的IP地址,切記。這里也可以使用'%'代替所有ip
(2)password就是Mysql數據庫root用戶的password,根據實際情況需要修改
三、再次用Mysql客戶端登陸
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/bjblues/archive/2008/02/04/2083934.aspx
select id, username from user where id>1
INTERSECT
select id, username from user where id<3
can simply be rewritten to
select id, username from user inner join
(select id, username from user where id <3) as b using (id, username)
where id>1
package com.founder.demo;
import Java.sql.Connection;
import Java.sql.DriverManager;
import Java.sql.PreparedStatement;
import Java.sql.ResultSet;
import Java.sql.Statement;
public class ImportCSV {
public static void main(String[] args) {
try {
// load the driver into memory
Class.forName("org.relique.jdbc.csv.CsvDriver");
// create a connection. The first command line parameter is assumed to
// be the directory in which the .csv files are held
Connection conn = DriverManager
.getConnection("jdbc:relique:csv:H:\\PythonWorkSpace");
// create a Statement object to execute the query with
Statement stmt = conn.createStatement();
// Select the columns from csv file
ResultSet results = stmt
.executeQuery("SELECT ORDER_NO,ARTICLE_NO,CATALOG_NO,DESCRIPTION,QUANTITY,ISO_UNIT,UNIT,MDL_NO,CAS, "
+ " MOLECULA,FORMULA,DENSITY,PRICE_EUR,UN_NO,DANGER_GR,DANGER_CLASS,ZUSATZGEFAHR1,ZUSATZGEFAHR2,R_PHRASES, "
+ " S_PHRASES,DANGER_SYMBOL,STORAGE_TEMPERATURE FROM ABCR");
//MySQL
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con = Java.sql.DriverManager
.getConnection(
"jdbc:mysql://localhost/chemicaldb?useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull",
"root", "root");
String sql = "INSERT INTO meryer_abcr (ORDER_NO,ARTICLE_NO,CATALOG_NO,DESCRIPTION,QUANTITY,ISO_UNIT,UNIT,MDL_NO,CAS, "
+ " MOLECULA_FORMULA,MOLECULAR_WEIGHT,DENSITY,PRICE_EUR,UN_NO,DANGER_GROUP,DANGER_CLASS,ZUSATZGEFAHR1,ZUSATZGEFAHR2,R_PHRASES, "
+ " S_PHRASES,DANGER_SYMBOL,STORAGE_TEMPERATURE) values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
PreparedStatement mstmt = con.prepareStatement(sql);
// dump out the results and set params
while (results.next()) {
mstmt.setString(1, results.getString("ORDER_NO"));
mstmt.setString(2, results.getString("ARTICLE_NO"));
mstmt.setString(3, results.getString("CATALOG_NO"));
mstmt.setString(4, results.getString("DESCRIPTION"));
mstmt.setString(5, results.getString("QUANTITY"));
mstmt.setString(6, results.getString("ISO_UNIT"));
mstmt.setString(7, results.getString("UNIT"));
mstmt.setString(8, results.getString("MDL_NO"));
mstmt.setString(9, results.getString("CAS"));
mstmt.setString(10, results.getString("MOLECULA_FORMULA"));
mstmt.setString(11, results.getString("MOLECULAR_WEIGHT"));
mstmt.setString(12, results.getString("DENSITY"));
mstmt.setString(13, results.getString("PRICE_EUR"));
mstmt.setString(14, results.getString("UN_NO"));
mstmt.setString(15, results.getString("DANGER_GROUP"));
mstmt.setString(16, results.getString("DANGER_CLASS"));
mstmt.setString(17, results.getString("ZUSATZGEFAHR1"));
mstmt.setString(18, results.getString("ZUSATZGEFAHR2"));
mstmt.setString(19, results.getString("R_PHRASES"));
mstmt.setString(20, results.getString("S_PHRASES"));
mstmt.setString(21, results.getString("DANGER_SYMBOL"));
mstmt.setString(22, results.getString("STORAGE_TEMPERATURE"));
mstmt.execute();
System.out.println(results.getString("ORDER_NO"));
}
// clean up
mstmt.close();
con.close();
results.close();
stmt.close();
conn.close();
} catch (Exception e) {
System.out.println("Oops-> " + e);
}
}
}
其實很簡單,和操作數據庫一樣,提供了類似數據中的SQL語句來操作CSV文件中的數據。
#encoding=utf-8
from __future__ import with_statement
import MySQLdb
import urllib
from lister import ListerTR
conn = MySQLdb.connect(host="localhost", user="root", passwd="root", db="coocoo", charset="utf8")
cursor = conn.cursor()
cursor.execute("select id, enname from compound where enname != '' and zhname = '' order by id")
row=cursor.fetchall()
for r in row:
params = urllib.urlencode({'eng2chi':r[1]}) 這里組織參數
sock = urllib.urlopen("http://202.127.145.134/scdb/translate/translate.asp", params) 發送請求,并把參數傳過去
html = sock.read()
sock.close()
p = ListerTR() 以下為解析返回的數據代碼
p.feed(html)
html = p.html
if u"成功" in html:
value = p.values[5]
data = value.strip()
print r[0], r[1], data 取回翻譯成功的內容更新數據庫里面的值
cursor.execute("update compound set zhname = %s where id=%s", (data, r[0]))
conn.commit()
else: 把翻譯失敗的記錄給文本文件中
with open('failture.txt', 'a+') as f:
f.write(str(r[0])+" | "+str(r[1]))
f.write('\n')
cursor.close()
conn.close()
mysql-5.0.19.tar.gz
二. 安裝環境:
主服務器: 192.168.0.201
從服務器: 192.168.0.00
三.主服務器配置:
Ø 建立用戶
grant replication slave on *.* to user001@192.168.0.200 identified by ‘111111′
Ø 編輯配置文件/etc/my.cnf
server-id = 1
log-bin=mysql-bin
binlog-do-db=test
binlog-ignore-db=mysql
注:
# grant replication slave on *.* to ‘用戶名’@'主機’ identified by ‘密碼’;
# binlog-do-db=需要備份的數據庫名,可寫多行
# binlog-ignore-db=不需要備份的數據庫名,可寫多行
# 可在B Slave上做連接測試: mysql -h 192.168.0.200 -u test -p
四.從服務器配置:
Ø 編輯/etc/my.cnf
server-id=2
server-id=2 記得是兩個???
log-bin=mysql-bin
master-host=192.168.0.201
master-user=user001
master-password=111111
master-port=3306
replicate-do-db=test
replicate-do-db=test1
# replicate-do-db=test 需要備份的數據庫名
# replicate-ignore-db=mysql 忽略的數據庫
# master-connect-retry=60 如果從服務器發現主服務器斷掉,重新連接的時間差(秒)
先手動同步一下主從服務器中要備份的數據庫,再重啟主,從服務器。
五.驗證是否配置正確:
# mysql> slave start;
# mysql> show slave status\G;
*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.0.201
Master_User: repluser1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000045
Read_Master_Log_Pos: 212
Relay_Log_File: sky-relay-bin.000054
Relay_Log_Pos: 235
Relay_Master_Log_File: mysql-bin.000045
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Replicate_Do_DB: test,test1
Replicate_Ignore_DB:
Replicate_Do_Table:
Replicate_Ignore_Table:
Replicate_Wild_Do_Table:
Replicate_Wild_Ignore_Table:
Last_Errno: 0
Last_Error:
Skip_Counter: 0
Exec_Master_Log_Pos: 212
Relay_Log_Space: 235
Until_Condition: None
Until_Log_File:
Until_Log_Pos: 0
Master_SSL_Allowed: No
Master_SSL_CA_File:
Master_SSL_CA_Path:
Master_SSL_Cert:
Master_SSL_Cipher:
Master_SSL_Key:
Seconds_Behind_Master: 0
1 row in set (0.00 sec)
確如如下行一致:
Waiting for master to send event
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
其他: ++主服務器上的相關命令
show master status
show slave hosts
show logs
show binlog events
purge logs to ‘log_name’
purge logs before ‘date’
reset master(老版本flush master)
set sql_log_bin=
++從服務器上的相關命令
slave start
slave stop
SLAVE STOP IO_THREAD //此線程把master段的日志寫到本地
SLAVE start IO_THREAD
SLAVE STOP SQL_THREAD //此線程把寫到本地的日志應用于數據庫
SLAVE start SQL_THREAD
reset slave
SET GLOBAL SQL_SLAVE_SKIP_COUNTER
load data from master
show slave status(SUPER,REPLICATION CLIENT)
CHANGE MASTER TO MASTER_HOST=, MASTER_PORT=,MASTER_USER=, MASTER_PASSWORD= //動態改變master信息
PURGE MASTER [before ‘date’] 刪除master端已同步過的日志
++產生了mysql-bin.00000x文件可以刪除
附一: mysql無法啟動:
# /usr/local/mysql//bin/mysqld_safe --user=mysql --log-error=err.txt
# more err.txt 根據里面的提示信息進行判斷分析
附二: 解決mysql“Access denied for user 'root'@'localhost'”
mysql -uroot -p
Enter password:
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)
修改root用戶的密碼:
# mysqladmin -uroot -p password 'newpassword' -
文章出處:http://www.diybl.com/course/6_system/linux/Linuxjs/2008622/127458.html
另一種辦法是在數據庫設計的時候,可能需要大小寫敏感,解決方法是建表時候使用BINARY標示。
CREATE TABLE students(
name VARCHAR(10) BINARY
);
--條件1 UPDATE Personnel SET salary = salary * 0.9 WHERE salary >= 5000; --條件2 UPDATE Personnel SET salary = salary * 1.15 WHERE salary >= 2000 AND salary < 4600;
UPDATE Personnel SET salary = CASE WHEN salary >= 5000 THEN salary * 0.9 WHEN salary >= 2000 AND salary < 4600 THEN salary * 1.15 ELSE salary END;
p_key | col_1 | col_2 |
a | 1 | 張三 |
b | 2 | 李四 |
c | 3 | 王五 |
a
和b
相互交換。用Case函數來實現的話,代碼如下 UPDATE SomeTable SET p_key = CASE WHEN p_key = 'a' THEN 'b' WHEN p_key = 'b' THEN 'a' ELSE p_key END WHERE p_key IN ('a', 'b');
--使用IN的時候 SELECT keyCol, CASE WHEN keyCol IN ( SELECT keyCol FROM tbl_B ) THEN 'Matched' ELSE 'Unmatched' END Label FROM tbl_A; --使用EXISTS的時候 SELECT keyCol, CASE WHEN EXISTS ( SELECT * FROM tbl_B WHERE tbl_A.keyCol = tbl_B.keyCol ) THEN 'Matched' ELSE 'Unmatched' END Label FROM tbl_A;
學號(std_id) | 課程ID(class_id) | 課程名(class_name) | 主修flag(main_class_flg) |
100 | 1 | 經濟學 | Y |
100 | 2 | 歷史學 | N |
200 | 2 | 歷史學 | N |
200 | 3 | 考古學 | Y |
200 | 4 | 計算機 | N |
300 | 4 | 計算機 | N |
400 | 5 | 化學 | N |
500 | 6 | 數學 | N |
--條件1:只選擇了一門課程的學生 SELECT std_id, MAX(class_id) AS main_class FROM Studentclass GROUP BY std_id HAVING COUNT(*) = 1;
STD_ID MAIN_class
------ ----------
300 4
400 5
500 6
--條件2:選擇多門課程的學生 SELECT std_id, class_id AS main_class FROM Studentclass WHERE main_class_flg = 'Y' ;
STD_ID MAIN_class
------ ----------
100 1
200 3
SELECT std_id, CASE WHEN COUNT(*) = 1 --只選擇一門課程的學生的情況 THEN MAX(class_id) ELSE MAX(CASE WHEN main_class_flg = 'Y' THEN class_id ELSE NULL END ) END AS main_class FROM Studentclass GROUP BY std_id;
STD_ID MAIN_class
------ ----------
100 1
200 3
300 4
400 5
500 6
CASE col_1 WHEN 1 THEN 'Right' WHEN NULL THEN 'Wrong' END
--簡單Case函數 CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END --Case搜索函數 CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END
--比如說,下面這段SQL,你永遠無法得到“第二類”這個結果 CASE WHEN col_1 IN ( 'a', 'b') THEN '第一類' WHEN col_1 IN ('a') THEN '第二類' ELSE'其他' END
國家(country) | 人口(population) |
中國 | 600 |
美國 | 100 |
加拿大 | 100 |
英國 | 200 |
法國 | 300 |
日本 | 250 |
德國 | 200 |
墨西哥 | 50 |
印度 | 250 |
洲 | 人口 |
亞洲 | 1100 |
北美洲 | 250 |
其他 | 700 |
SELECT SUM(population), CASE country WHEN '中國' THEN '亞洲' WHEN '印度' THEN '亞洲' WHEN '日本' THEN '亞洲' WHEN '美國' THEN '北美洲' WHEN '加拿大' THEN '北美洲' WHEN '墨西哥' THEN '北美洲' ELSE '其他' END FROM Table_A GROUP BY CASE country WHEN '中國' THEN '亞洲' WHEN '印度' THEN '亞洲' WHEN '日本' THEN '亞洲' WHEN '美國' THEN '北美洲' WHEN '加拿大' THEN '北美洲' WHEN '墨西哥' THEN '北美洲' ELSE '其他' END;
SELECT CASE WHEN salary <= 500 THEN '1' WHEN salary > 500 AND salary <= 600 THEN '2' WHEN salary > 600 AND salary <= 800 THEN '3' WHEN salary > 800 AND salary <= 1000 THEN '4' ELSE NULL END salary_class, COUNT(*) FROM Table_A GROUP BY CASE WHEN salary <= 500 THEN '1' WHEN salary > 500 AND salary <= 600 THEN '2' WHEN salary > 600 AND salary <= 800 THEN '3' WHEN salary > 800 AND salary <= 1000 THEN '4' ELSE NULL END;
國家(country) | 性別(sex) | 人口(population) |
中國 | 1 | 340 |
中國 | 2 | 260 |
美國 | 1 | 45 |
美國 | 2 | 55 |
加拿大 | 1 | 51 |
加拿大 | 2 | 49 |
英國 | 1 | 40 |
英國 | 2 | 60 |
國家 | 男 | 女 |
中國 | 340 | 260 |
美國 | 45 | 55 |
加拿大 | 51 | 49 |
英國 | 40 | 60 |
SELECT country, SUM( CASE WHEN sex = '1' THEN population ELSE 0 END), --男性人口 SUM( CASE WHEN sex = '2' THEN population ELSE 0 END) --女性人口 FROM Table_A GROUP BY country;
CONSTRAINT check_salary CHECK ( CASE WHEN sex = '2' THEN CASE WHEN salary > 1000 THEN 1 ELSE 0 END ELSE 1 END = 1 )
CONSTRAINT check_salary CHECK ( sex = '2' AND salary > 1000 )
USE pubs GO SELECT CASE WHEN price IS NULL THEN 'Unpriced' WHEN price < 10 THEN 'Bargain' WHEN price BETWEEN 10 and 20 THEN 'Average' ELSE 'Gift to impress relatives' END AS Range, Title FROM titles GROUP BY CASE WHEN price IS NULL THEN 'Unpriced' WHEN price < 10 THEN 'Bargain' WHEN price BETWEEN 10 and 20 THEN 'Average' ELSE 'Gift to impress relatives' END, Title ORDER BY CASE WHEN price IS NULL THEN 'Unpriced' WHEN price < 10 THEN 'Bargain' WHEN price BETWEEN 10 and 20 THEN 'Average' ELSE 'Gift to impress relatives' END, Title GO
CREATE DATABASE student
2.如何刪除數據庫
DROP DATABASE student
3.如何備份數據庫到磁盤文件
BACKUP DATABASE student to disk=´c:\1234.bak´
4.如何從磁盤文件還原數據庫
RESTORE DATABASE studnet FROM DISK = ´c:\1234.bak´
5.怎樣創建表?
CREATE TABLE Students (
ID int IDENTITY ( 1, 1), --自增字段,基數1,步長1
StudentID char (4) NOT NULL ,
Name char (10) NOT NULL ,
Age int NULL ,
Birthday datetime NULL,
CONSTRAINT PK_Students PRIMARY KEY (StudentID) --設置主鍵
)
CREATE TABLE Subjects (
ID int IDENTITY ( 1, 1), --自增字段,基數1,步長1
ClassID char (4) NOT NULL ,
ClassName char (10) NOT NULL,
CONSTRAINT PK_Subjects PRIMARY KEY (ClassID) --設置主鍵
)
CREATE TABLE Scores (
ID int IDENTITY ( 1, 1), --自增字段,基數1,步長1
StudentID char (4) NOT NULL ,
ClassID char (4) NOT NULL ,
Score float NOT NULL,
CONSTRAINT FK_Scores_Students FOREIGN KEY (StudentID) REFERENCES Students(StudentID), --設置外鍵
CONSTRAINT FK_Scores_Subjects FOREIGN KEY (ClassID) REFERENCES Subjects(ClassID), --設置外鍵
CONSTRAINT PK_Scores PRIMARY KEY (StudentID,ClassID) --設置主鍵
)
6.怎樣刪除表?
DROP TABLE Students
7.怎樣創建視圖?
CREATE VIEW s_s_s
AS
SELECT Students.Name, Subjects.ClassName, Scores.Score
FROM Scores INNER JOIN
Students ON Scores.StudentID = Students.StudentID INNER JOIN
Subjects ON Scores.ClassID = Subjects.ClassID
8.怎樣刪除視圖?
DROP VIEW s_s_s
9.如何創建存儲過程?
CREATE PROCEDURE GetStudent
@age INT,
@birthday DATETIME
AS
SELECT *
FROM students
WHERE Age = @age AND Birthday = @birthday
GO
10.如何刪除存儲過程?
DROP PROCEDURE GetStudent
11.如何創建觸發器?
CREATE TRIGGER reminder
ON Students
FOR INSERT, UPDATE, DELETE
AS
EXEC master..xp_sendmail ´MaryM´,
´Don´´t forget to print a report for the distributors.´
GO
12.如何刪除觸發器?
DROP TRIGGER reminder
13.如何創建索引?
CREATE UNIQUE INDEX IX_Students ON Students (Name)
14.如何刪除索引?
DROP INDEX Students.IX_Students
15.怎樣給表添加字段?
ALTER TABLE Students ADD Address varchar (50) NULL
16.怎樣刪除表中某個字段?
ALTER TABLE Students DROP COLUMN Address
17.如何設置列的標識屬性?
沒找到辦法
18.如何去掉列的標識屬性?
沒有找到好的方法,只能是先添加一列,然后把標識列的值更新到新加入的列,刪除標識列,再用與標識列相同的名字類型添加一列,用前面加入的列更新該列.如果該標識列是其他表的外鍵,還要先刪除外鍵約束,很麻煩.誰有好的辦法,還請告訴我.
19.如何重設標識列的標識種子?
DBCC CHECKIDENT (Student, RESEED, 1)
20.怎樣給表加上主鍵?
ALTER TABLE Scores ADD CONSTRAINT PK_Scores PRIMARY KEY (StudentID,ClassID)
21.怎樣刪除表的主鍵?
ALTER TABLE Scores DROP CONSTRAINT PK_Scores
22.怎樣給表添加一個外鍵?
ALTER TABLE Scores ADD CONSTRAINT FK_Scores_Students FOREIGN KEY (StudentID) REFERENCES Students (StudentID) ON DELETE CASCADE
23.怎樣刪除表的一個外鍵?
ALTER TABLE Scores DROP CONSTRAINT FK_Scores_Students
24.怎樣給字段加上CHECK約束?
ALTER TABLE Students ADD CONSTRAINT CK_Students CHECK (Age > 0)
25.怎樣去掉字段上的CHECK約束?
ALTER TABLE Students DROP CONSTRAINT CK_Students
26.怎樣給字段設置默認值?
ALTER TABLE Students ADD CONSTRAINT DF_Students_Age DEFAULT (18) FOR Age
27.怎樣移去字段的默認值?
ALTER TABLE Students DROP CONSTRAINT DF_Students_Age
28.修改字段的類型及非空約束
ALTER TABLE Students ALTER COLUMN Age char (10) null
ALTER TABLE Students ALTER COLUMN Age int not null
mysqldump -u root -p --default-character-set=gbk testAcegi > c:\testAcegiDump.sql
mysqldump -u root -p --default-character-set=gbk knightsoft > c:\knightsoft.sql
1. 使用
import MySQLdb
1.1. 連接
conn = MySQLdb.Connection(host, user, password, dbname)
1.2. 選擇數據庫,如果上面沒有指定數據庫,則使用此方法指定!
conn.select_db(’database name’)
1.3. 獲得cursor
cur = conn.cursor()
1.4. cursor位置設定
cur.scroll(int, mode)
mode可為相對位置或者絕對位置,分別為relative和absolute。
1.5. select
cur.execute(‘select clause’)
例如
cur.execute(‘select * from mytable’)
row = cur.fetchall()
或者:
row1 = cur.fetchone()
1.6. insert
cur.execute(‘inset clause’)
例如
cur.execute("insert into user (Name, Password) values ('maggie','12345')")
conn.commit()
1.7. update
cur.execute(‘update clause’)
例如
cur.execute("update user set Name = 'eric chau' where id = 1")
conn.commit()
1.8. delete
cur.execute(‘delete clause’)
例如
cur.execute("delete from user where id = 1")
conn.commit()
完整代碼:
from MySQLdb import Connect
def conn():
#conn = Connect('localhost','root','root')
#conn.select_db('eric')
conn = Connect('localhost','root','root','eric')
cur = conn.cursor()
cur.execute('select * from user')
cur.scroll(0)
row1 = cur.fetchone()
print 'id:', row1[0]
print 'name:', row1[1]
print 'password:', row1[2]
#cur.execute("insert into user (Name, Password) values ('maggie','12345')")
#cur.execute("update user set Name = 'eric chau' where id = 1")
cur.execute("delete from user where id = 11")
conn.commit()
if __name__=='__main__':
conn()