`

mysql 语法入门 5

阅读更多

7.17 UPDATE句法

UPDATE [LOW_PRIORITY] tbl_name SET col_name1=expr1,col_name2=expr2,...
    [WHERE where_definition] [LIMIT #]

UPDATE用新值更新现存表中行的列,SET子句指出哪个列要修改和他们应该被给定的值,WHERE子句,如果给出,指定哪个行应该被更新,否则所有行被更新。

如果你指定关键词LOW_PRIORITY,执行UPDATE被推迟到没有其他客户正在读取表时。

如果你从一个表达式的tbl_name存取列,UPDATE使用列的当前值。例如,下列语句设置age为它的当前值加1:

mysql> UPDATE persondata SET age=age+1;

UPDATE赋值是从左到右计算。例如,下列语句两倍age列,然后加1:

mysql> UPDATE persondata SET age=age*2, age=age+1;

如果你设置列为其它当前有的值,MySQL注意到这点并且不更新它。

UPDATE返回实际上被改变的行的数量。在MySQL 3.22或以后版本中,C API函数mysql_info()返回被匹配并且更新的行数和在UPDATE期间发生警告的数量。

MySQL3.23中,你可使用LIMIT #来保证只有一个给定数量的行被改变。

 

7.18 USE句法

USE db_name 

USE db_name语句告诉MySQL使用db_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数据库中的author表和db2数据库中的editor表:

mysql> USE db1;
mysql> SELECT author_name,editor_name FROM author,db2.editor
           WHERE author.editor_id = db2.editor.editor_id;

USE语句提供了Sybase的兼容性。

 

7.19 FLUSH句法(清除缓存)

FLUSH flush_option [,flush_option]

如果你想要清除一些MySQL使用内部缓存,你应该使用FLUSH命令。为了执行FLUSH,你必须有reload权限。

flush_option可以是下列任何东西:

HOSTS 清空主机缓存表。如果你的某些主机改变IP数字,或如果你得到错误消息Host ... is blocked,你应该清空主机表。当在连接MySQL服务器时,对一台给定的主机有多于max_connect_errors个错误连续不断地发生,MySQL认定某些东西错了并且阻止主机进一步的连接请求。清空主机表允许主机再尝试连接。见18.2.3 Host '...' is blocked错误)。你可用-O max_connection_errors=999999999启动mysqld来避免这条错误消息。
LOGS 关闭并且再打开标准和更新记录文件。如果你指定了一个没有扩展名的更新记录文件,新的更新记录文件的扩展数字将相对先前的文件加1。
PRIVILEGES mysql数据库授权表中重新装载权限。
TABLES 关闭所有打开的表。
STATUS 重置大多数状态变量到0。

你也可以用mysqladmin实用程序,使用flush-hosts, flush-logs, reloadflush-tables命令来访问上述的每一个命令。

 

7.20 KILL句法

KILL thread_id 

每个对mysqld的连接以一个单独的线程运行。你可以用看SHOW PROCESSLIST命令察看哪个线程正在运行,并且用KILL thread_id命令杀死一个线程。

如果你有process权限,你能看到并且杀死所有线程。否则,你只能看到并且杀死你自己的线程。

你也可以使用mysqladmin processlistmysqladmin kill命令检查并杀死线程。

7.21 SHOW句法 (得到表,列等的信息)

   SHOW DATABASES [LIKE wild]
or SHOW TABLES [FROM db_name] [LIKE wild]
or SHOW COLUMNS FROM tbl_name [FROM db_name] [LIKE wild]
or SHOW INDEX FROM tbl_name [FROM db_name]
or SHOW STATUS
or SHOW VARIABLES [LIKE wild]
or SHOW [FULL] PROCESSLIST
or SHOW TABLE STATUS [FROM db_name] [LIKE wild]
or SHOW GRANTS FOR user

SHOW提供关于数据库、桌子、列或服务器的信息。如果使用LIKE wild部分,wild字符串可以是一个使用SQL的“%”“_”通配符的字符串。

你能使用db_name.tbl_name作为tbl_name FROM db_name句法的另一种选择。这两个语句是相等的:

mysql> SHOW INDEX FROM mytable FROM mydb;
mysql> SHOW INDEX FROM mydb.mytable;

SHOW DATABASES列出在MySQL服务器主机上的数据库。你也可以用mysqlshow命令得到这张表。

SHOW TABLES列出在一个给定的数据库中的表。你也可以用mysqlshow db_name命令得到这张表。

注意:如果一个用户没有一个表的任何权限,表将不在SHOW TABLESmysqlshow db_name中的输出中显示。

SHOW COLUMNS列出在一个给定表中的列。如果列类型不同于你期望的是基于CREATE TABLE语句的那样,注意,MySQL有时改变列类型。见7.7.1 隐含的列说明变化

DESCRIBE语句提供了类似SHOW COLUMNS的信息。见7.23 DESCRIBE 句法 (得到列的信息)

SHOW TABLE STATUS(在版本3.23引入)运行类似SHOW STATUS,但是提供每个表的更多信息。你也可以使用mysqlshow --status db_name命令得到这张表。下面的列被返回:

含义
Name 表名
Type 表的类型 (ISAM,MyISAM或HEAP)
Row_format 行存储格式 (固定, 动态, 或压缩)
Rows 行数量
Avg_row_length 平均行长度
Data_length 数据文件的长度
Max_data_length 数据文件的最大长度
Index_length 索引文件的长度
Data_free 已分配但未使用了字节数
Auto_increment 下一个 autoincrement(自动加1)值
Create_time 表被创造的时间
Update_time 数据文件最后更新的时间
Check_time 最后对表运行一个检查的时间
Create_options CREATE TABLE一起使用的额外选项
Comment 当创造表时,使用的注释 (或为什么MySQL不能存取表信息的一些信息)。

SHOW FIELDSSHOW COLUMNS一个同义词,SHOW KEYSSHOW INDEX一个同义词。你也可以用mysqlshow db_name tbl_namemysqlshow -k db_name tbl_name 列出一张表的列或索引。

SHOW INDEX以非常相似于ODBC的SQLStatistics调用的格式返回索引信息。下面的列被返回:

含义
Table 表名
Non_unique 0,如果索引不能包含重复。
Key_name 索引名
Seq_in_index 索引中的列顺序号, 从 1 开始。
Column_name 列名。
Collation 列怎样在索引中被排序。在MySQL中,这可以有值A(升序) 或NULL(不排序)。
Cardinality 索引中唯一值的数量。这可通过运行isamchk -a更改.
Sub_part 如果列只是部分被索引,索引字符的数量。NULL,如果整个键被索引。

SHOW STATUS提供服务器的状态信息(象mysqladmin extended-status一样)。输出类似于下面的显示,尽管格式和数字可以有点不同:

+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| Aborted_clients          | 0      |
| Aborted_connects         | 0      |
| Connections              | 17     |
| Created_tmp_tables       | 0      |
| Delayed_insert_threads   | 0      |
| Delayed_writes           | 0      |
| Delayed_errors           | 0      |
| Flush_commands           | 2      |
| Handler_delete           | 2      |
| Handler_read_first       | 0      |
| Handler_read_key         | 1      |
| Handler_read_next        | 0      |
| Handler_read_rnd         | 35     |
| Handler_update           | 0      |
| Handler_write            | 2      |
| Key_blocks_used          | 0      |
| Key_read_requests        | 0      |
| Key_reads                | 0      |
| Key_write_requests       | 0      |
| Key_writes               | 0      |
| Max_used_connections     | 1      |
| Not_flushed_key_blocks   | 0      |
| Not_flushed_delayed_rows | 0      |
| Open_tables              | 1      |
| Open_files               | 2      |
| Open_streams             | 0      |
| Opened_tables            | 11     |
| Questions                | 14     |
| Slow_queries             | 0      |
| Threads_connected        | 1      |
| Threads_running          | 1      |
| Uptime                   | 149111 |
+--------------------------+--------+

上面列出的状态变量有下列含义:

Aborted_clients 由于客户没有正确关闭连接已经死掉,已经放弃的连接数量。
Aborted_connects 尝试已经失败的MySQL服务器的连接的次数。
Connections 试图连接MySQL服务器的次数。
Created_tmp_tables 当执行语句时,已经被创造了的隐含临时表的数量。
Delayed_insert_threads 正在使用的延迟插入处理器线程的数量。
Delayed_writes INSERT DELAYED写入的行数。
Delayed_errors INSERT DELAYED写入的发生某些错误(可能重复键值)的行数。
Flush_commands 执行FLUSH命令的次数。
Handler_delete 请求从一张表中删除行的次数。
Handler_read_first 请求读入表中第一行的次数。
Handler_read_key 请求数字基于键读行。
Handler_read_next 请求读入基于一个键的一行的次数。
Handler_read_rnd 请求读入基于一个固定位置的一行的次数。
Handler_update 请求更新表中一行的次数。
Handler_write 请求向表中插入一行的次数。
Key_blocks_used 用于关键字缓存的块的数量。
Key_read_requests 请求从缓存读入一个键值的次数。
Key_reads 从磁盘物理读入一个键值的次数。
Key_write_requests 请求将一个关键字块写入缓存次数。
Key_writes 将一个键值块物理写入磁盘的次数。
Max_used_connections 同时使用的连接的最大数目。
Not_flushed_key_blocks 在键缓存中已经改变但是还没被清空到磁盘上的键块。
Not_flushed_delayed_rows INSERT DELAY队列中等待写入的行的数量。
Open_tables 打开表的数量。
Open_files 打开文件的数量。
Open_streams 打开流的数量(主要用于日志记载)
Opened_tables 已经打开的表的数量。
Questions 发往服务器的查询的数量。
Slow_queries 要花超过long_query_time时间的查询数量。
Threads_connected 当前打开的连接的数量。
Threads_running 不在睡眠的线程数量。
Uptime 服务器工作了多少秒。

关于上面的一些注释:

  • 如果Opened_tables太大,那么你的table_cache变量可能太小。
  • 如果key_reads太大,那么你的key_cache可能太小。缓存命中率可以用key_reads/key_read_requests计算。
  • 如果Handler_read_rnd太大,那么你很可能有大量的查询需要MySQL扫描整个表或你有没正确使用键值的联结(join)。

SHOW VARIABLES显示出一些MySQL系统变量的值,你也能使用mysqladmin variables命令得到这个信息。如果缺省值不合适,你能在mysqld启动时使用命令行选项来设置这些变量的大多数。输出类似于下面的显示,尽管格式和数字可以有点不同:

+------------------------+--------------------------+
| Variable_name          | Value                    |
+------------------------+--------------------------+
| back_log               | 5                        |
| connect_timeout        | 5                        |
| basedir                | /my/monty/               |
| datadir                | /my/monty/data/          |
| delayed_insert_limit   | 100                      |
| delayed_insert_timeout | 300                      |
| delayed_queue_size     | 1000                     |
| join_buffer_size       | 131072                   |
| flush_time             | 0                        |
| interactive_timeout    | 28800                    |
| key_buffer_size        | 1048540                  |
| language               | /my/monty/share/english/ |
| log                    | OFF                      |
| log_update             | OFF                      |
| long_query_time        | 10                       |
| low_priority_updates   | OFF                      |
| max_allowed_packet     | 1048576                  |
| max_connections        | 100                      |
| max_connect_errors     | 10                       |
| max_delayed_threads    | 20                       |
| max_heap_table_size    | 16777216                 |
| max_join_size          | 4294967295               |
| max_sort_length        | 1024                     |
| max_tmp_tables         | 32                       |
| net_buffer_length      | 16384                    |
| port                   | 3306                     |
| protocol-version       | 10                       |
| record_buffer          | 131072                   |
| skip_locking           | ON                       |
| socket                 | /tmp/mysql.sock          |
| sort_buffer            | 2097116                  |
| table_cache            | 64                       |
| thread_stack           | 131072                   |
| tmp_table_size         | 1048576                  |
| tmpdir                 | /machine/tmp/            |
| version                | 3.23.0-alpha-debug       |
| wait_timeout           | 28800                    |
+------------------------+--------------------------+

10.2.3 调节服务器参数

SHOW PROCESSLIST显示哪个线程正在运行,你也能使用mysqladmin processlist命令得到这个信息。如果你有process权限, 你能看见所有的线程,否则,你仅能看见你自己的线程。见7.20 KILL句法。如果你不使用FULL选项,那么每个查询只有头100字符被显示出来。

SHOW GRANTS FOR user列出对一个用户必须发出以重复授权的授权命令。

mysql> SHOW GRANTS FOR root@localhost;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root''localhost' WITH GRANT OPTION  |
+---------------------------------------------------------------------+
  

7.22 EXPLAIN句法(得到关于SELECT的信息)

    EXPLAIN tbl_name
or  EXPLAIN SELECT select_options

EXPLAIN tbl_nameDESCRIBE tbl_nameSHOW COLUMNS FROM tbl_name的一个同义词。

当你在一条SELECT语句前放上关键词EXPLAINMySQL解释它将如何处理SELECT,提供有关表如何联结和以什么次序联结的信息。

借助于EXPLAIN,你可以知道你什么时候必须为表加入索引以得到一个使用索引找到记录的更快的SELECT。你也能知道优化器是否以一个最佳次序联结表。为了强制优化器对一个SELECT语句使用一个特定联结次序,增加一个STRAIGHT_JOIN子句。

对于非简单的联结,EXPLAIN为用于SELECT语句中的每个表返回一行信息。表以他们将被读入的顺序被列出。MySQL用一边扫描多次联结的方式解决所有联结,这意味着MySQL从第一个表中读一行,然后找到在第二个表中的一个匹配行,然后在第3个表中等等。当所有的表被处理完,它输出选择的列并且回溯表列表直到找到一个表有更多的匹配行,从该表读入下一行并继续处理下一个表。

EXPLAIN的输出包括下面列:

table
输出的行所引用的表。
type
联结类型。各种类型的信息在下面给出。
possible_keys
possible_keys列指出MySQL能使用哪个索引在该表中找到行。注意,该列完全独立于表的次序。这意味着在possible_keys中的某些键实际上不能以生成的表次序使用。如果该列是空的,没有相关的索引。在这种情况下,你也许能通过检验WHERE子句看是否它引用某些列或列不是适合索引来提高你的查询性能。如果是这样,创造一个适当的索引并且在用EXPLAIN检查查询。见7.8 ALTER TABLE句法。为了看清一张表有什么索引,使用SHOW INDEX FROM tbl_name
key
key列显示MySQL实际决定使用的键。如果没有索引被选择,键是NULL
key_len
key_len列显示MySQL决定使用的键长度。如果键是NULL,长度是NULL。注意这告诉我们MySQL将实际使用一个多部键值的几个部分。
ref
ref列显示哪个列或常数与key一起用于从表中选择行。
rows
rows列显示MySQL相信它必须检验以执行查询的行数。
Extra
如果Extra列包括文字Only index,这意味着信息只用索引树中的信息检索出的。通常,这比扫描整个表要快。如果Extra列包括文字where used,它意味着一个WHERE子句将被用来限制哪些行与下一个表匹配或发向客户。

不同的联结类型列在下面,以最好到最差类型的次序:

system
桌子仅有一行(=系统表)。这是const联结类型的一个特例。
const
桌子有最多一个匹配行,它将在查询开始时被读取。因为仅有一行,在这行的列值可被剩下的优化器认为是常数。 const表很快,因为它们只读取一次!
eq_ref
对于每个来自于先前的表的行组合,从该表中读取一行。这可能是最好的联结类型,除了const类型。它用在一个索引的所有部分被联结使用并且索引是UNIQUEPRIMARY KEY
ref
对于每个来自于先前的表的行组合,所有有匹配索引值的行将从这张表中读取。如果联结只使用键的最左面前缀,或如果键不是UNIQUEPRIMARY KEY(换句话说,如果联结不能基于键值选择单个行的话),使用ref。如果被使用的键仅仅匹配一些行,该联结类型是不错的。
range
只有在一个给定范围的行将被检索,使用一个索引选择行。ref列显示哪个索引被使用。
index
这与ALL相同,除了只有索引树被扫描。这通常比ALL快,因为索引文件通常比数据文件小。
ALL
对于每个来自于先前的表的行组合,将要做一个完整的表扫描。如果表格是第一个没标记const的表,这通常不好,并且通常在所有的其他情况下差。你通常可以通过增加更多的索引来避免ALL,使得行能从早先的表中基于常数值或列值被检索出。

通过相乘EXPLAIN输出的rows行的所有值,你能得到一个关于一个联结要多好的提示。这应该粗略地告诉你MySQL必须检验多少行以执行查询。当你使用max_join_size变量限制查询时,也用这个数字。见10.2.3 调节服务器参数

下列例子显示出一个JOIN如何能使用EXPLAIN提供的信息逐步被优化。

假定你有显示在下面的SELECT语句,你使用EXPLAIN检验:

EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
            tt.ProjectReference, tt.EstimatedShipDate,
            tt.ActualShipDate, tt.ClientID,
            tt.ServiceCodes, tt.RepetitiveID,
            tt.CurrentProcess, tt.CurrentDPPerson,
            tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
            et_1.COUNTRY, do.CUSTNAME
        FROM tt, et, et AS et_1, do
        WHERE tt.SubmitTime IS NULL
            AND tt.ActualPC = et.EMPLOYID
            AND tt.AssignedPC = et_1.EMPLOYID
            AND tt.ClientID = do.CUSTNMBR;

对于这个例子,假定:

  • 被比较的列被声明如下:
    列类型
    tt ActualPC CHAR(10)
    tt AssignedPC CHAR(10)
    tt ClientID CHAR(10)
    et EMPLOYID CHAR(15)
    do CUSTNMBR CHAR(15)
  • 表有显示在下面的索引:
    索引
    tt ActualPC
    tt AssignedPC
    tt ClientID
    et EMPLOYID(主键)
    do CUSTNMBR(主键)
  • tt.ActualPC值不是均匀分布的。

开始,在任何优化被施行前,EXPLAIN语句产生下列信息:

table type possible_keys                key  key_len ref  rows  Extra
et    ALL  PRIMARY                      NULL NULL    NULL 74
do    ALL  PRIMARY                      NULL NULL    NULL 2135
et_1  ALL  PRIMARY                      NULL NULL    NULL 74
tt    ALL  AssignedPC,ClientID,ActualPC NULL NULL    NULL 3872
      range checked for each record (key map: 35)

因为type对每张表是ALL,这个输出显示MySQL正在对所有表进行一个完整联结!这将花相当长的时间,因为必须检验每张表的行数的乘积次数!对于一个实例,这是74 * 2135 * 74 * 3872 = 45,268,558,720行。如果表更大,你只能想象它将花多长时间……

如果列声明不同,这里的一个问题是MySQL(还)不能高效地在列上使用索引。在本文中,VARCHARCHAR是相同的,除非他们声明为不同的长度。因为tt.ActualPC被声明为CHAR(10)并且et.EMPLOYID被声明为CHAR(15),有一个长度失配。

为了修正在列长度上的不同,使用ALTER TABLEActualPC的长度从10个字符变为15个字符:

mysql> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);

现在tt.ActualPCet.EMPLOYID都是VARCHAR(15),再执行EXPLAIN语句产生这个结果:

table type   possible_keys   key     key_len ref         rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL 3872    where used
do    ALL    PRIMARY         NULL    NULL    NULL        2135
      range checked for each record (key map: 1)
et_1  ALL    PRIMARY         NULL    NULL    NULL        74
      range checked for each record (key map: 1)
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC 1

这不是完美的,但是是好一些了(rows值的乘积少了一个74一个因子),这个版本在几秒内执行。

第2种改变能消除tt.AssignedPC = et_1.EMPLOYIDtt.ClientID = do.CUSTNMBR比较的列的长度失配:

mysql> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
                      MODIFY ClientID   VARCHAR(15);

现在EXPLAIN产生的输出显示在下面:

table type   possible_keys   key     key_len ref            rows     Extra
et    ALL    PRIMARY         NULL    NULL    NULL           74
tt    ref    AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

这“几乎”象它能得到的一样好。

剩下的问题是,缺省地,MySQL假设在tt.ActualPC列的值是均匀分布的,并且对tt表不是这样。幸好,很容易告诉MySQL关于这些:

shell> myisamchk --analyze PATH_TO_MYSQL_DATABASE/tt
shell> mysqladmin refresh

现在联结是“完美”的了,而且EXPLAIN产生这个结果:

table type   possible_keys   key     key_len ref            rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL    3872    where used
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC    1
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

注意在从EXPLAIN输出的rows列是一个来自MySQL联结优化器的“教育猜测”;为了优化查询,你应该检查数字是否接近事实。如果不是,你可以通过在你的SELECT语句里面使用STRAIGHT_JOIN并且试着在在FROM子句以不同的次序列出表,可能得到更好的性能。

 

7.23 DESCRIBE句法 (得到列的信息)

{DESCRIBE | DESC} tbl_name {col_name | wild}

DESCRIBE提供关于一张表的列的信息。col_name可以是一个列名字或包含SQL的“%”“_”通配符的一个字符串。

如果列类型不同于你期望的是基于一个CREATE TABLE语句,注意MySQL有时改变列类型。见7.7.1 隐含的列说明变化

这个语句为了与 Oracle 兼容而提供的。

SHOW语句提供类似的信息。见7.21 SHOW句法(得到表,列的信息)

 

7.24 LOCK TABLES/UNLOCK TABLES句法

LOCK TABLES tbl_name [AS alias] {READ | [LOW_PRIORITY] WRITE}
            [, tbl_name {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES为当前线程锁定表。UNLOCK TABLES释放被当前线程持有的任何锁。当线程发出另外一个LOCK TABLES时,或当服务器的连接被关闭时,当前线程锁定的所有表自动被解锁。

如果一个线程获得在一个表上的一个READ锁,该线程(和所有其他线程)只能从表中读。如果一个线程获得一个表上的一个WRITE锁,那么只有持锁的线程READWRITE表,其他线程被阻止。

每个线程等待(没有超时)直到它获得它请求的所有锁。

WRITE锁通常比READ锁有更高的优先级,以确保更改尽快被处理。这意味着,如果一个线程获得READ锁,并且然后另外一个线程请求一个WRITE锁, 随后的READ锁请求将等待直到WRITE线程得到了锁并且释放了它。当线程正在等待WRITE锁时,你可以使用LOW_PRIORITY WRITE允许其他线程获得READ锁。如果你肯定终于有个时刻没有线程将有一个READ锁,你应该只使用LOW_PRIORITY WRITE

当你使用LOCK TABLES时,你必须锁定你将使用的所有表!如果你正在一个查询中多次使用一张表(用别名),你必须对每个别名得到一把锁!这条政策保证表锁定不会死锁。

注意你应该锁定任何你正在用INSERT DELAYED使用的表,这是因为在这种情况下,INSERT被一个不同的线程执行。

通常,你不必锁定表,因为所有单个UPDATE语句是原语;没有其他线程能防碍任何其它正在执行SQL语句的线程。当你想锁定表,有一些情况:

  • 如果你将在一堆表上运行许多操作,锁定你将使用的表是较快的。当然缺点是,没有其他线程能更新一个READ锁定的表并且没有其他线程能读一个WRITE-锁定的表。
  • MySQL不支持事务环境,所以如果你想要保证在一个SELECT和一个UPDATE之间没有其他线程到来,你必须使用LOCK TABLES。下面显示的例子要求LOCK TABLES以便安全地执行:
    mysql> LOCK TABLES trans READ, customer WRITE;
    mysql> select sum(value) from trans where customer_id= some_id;
    mysql> update customer set totalvalue=sum_from_previous_statement
               where customer_id=some_id;
    mysql> UNLOCK TABLES;

没有LOCK TABLES,另外一个线程可能有一个机会在执行SELECTUPDATE语句之间往trans表中插入一个新行。

通过使用渐增更改(UPDATE customer SET value=value+new_value)或LAST_INSERT_ID()函数,在很多情况下你能使用LOCK TABLES来避免。

你也可以使用用户级锁定函数GET_LOCK()RELEASE_LOCK()解决一些情况,这些锁保存在服务器的一张哈希表中并且用pthread_mutex_lock()pthread_mutex_unlock()实现以获得高速度。见7.4.12 其他函数

有关锁定政策的更多信息,见10.2.8 MySQL 怎样锁定表

7.25 SET OPTION句法

SET [OPTION] SQL_VALUE_OPTION= value, ...

SET OPTION设置影响服务器或你的客户操作的各种选项。你设置的任何选择保持有效直到当前会话结束,或直到你设置选项为不同的值。

CHARACTER SET character_set_name | DEFAULT
这用给定的映射表从/到客户映射所有字符串。对character_set_name当前唯一的选项是 cp1251_koi8,但是你能容易通过编辑在MySQL源代码分发的“sql/convert.cc”文件增加新的映射。缺省映射能用character_set_nameDEFAULT值恢复。注意设置CHARACTER SET选项的语法不同于设置其他选项目的语法。
PASSWORD = PASSWORD('some password')
设置当前用户的口令。任何非匿名的用户能改变他自己的口令!
PASSWORD FOR user = PASSWORD('some password')
设置当前服务器主机上的一个特定用户的口令。只有具备存取mysql数据库的用户可以这样做。用户应该以user@hostname格式给出,这里userhostname完全与他们列在mysql.user表条目的UserHost列一样。例如,如果你有一个条目其UserHost字段是'bob''%.loc.gov',你将写成:
mysql> SET PASSWORD FOR bob@"%.loc.gov" = PASSWORD("newpass");

或

mysql> UPDATE mysql.user SET password=PASSWORD("newpass") where user="bob' and host="%.loc.gov";
SQL_AUTO_IS_NULL = 0 | 1
如果设置为1(缺省 ),那么对于一个具有一个自动加1的行的表,用下列构件能找出最后插入的行:WHERE auto_increment_column IS NULL。这被一些 ODBC 程序入Access使用。
SQL_BIG_TABLES = 0 | 1
如果设置为1,所有临时表存在在磁盘上而非内存中。这将更慢一些,但是对需要大的临时表的大SELECT操作,你将不会得到The table tbl_name is full的错误。对于一个新连接的缺省值是0(即,使用内存中的临时表)。
SQL_BIG_SELECTS = 0 | 1
如果设置为0,如果一个SELECT尝试可能花很长的时间,MySQL将放弃。这在一个不妥当的WHERE语句发出时是有用的。一个大的查询被定义为一个将可能必须检验多于max_join_size行的SELECT。对一个新连接的缺省值是1(它将允许所有SELECT语句)。
SQL_LOW_PRIORITY_UPDATES = 0 | 1
如果设置为1,所有INSERTUPDATEDELETELOCK TABLE WRITE语句等待,直到在受影响的表上没有未解决的SELECTLOCK TABLE READ
SQL_SELECT_LIMIT = value | DEFAULT
SELECT语句返回的记录的最大数量。如果一个SELECT有一个LIMIT子句,LIMIT优先与SQL_SELECT_LIMIT值。对一个新连接的缺省值是“无限”的。如果你改变了限制,缺省值能用SQL_SELECT_LIMIT的一个DEFAULT值恢复。
SQL_LOG_OFF = 0 | 1
如果设置为1,如果客户有process权限,对该客户没有日志记载到标准的日志文件中。这不影响更新日志记录!
SQL_LOG_UPDATE = 0 | 1
如果设置为0, 如果客户有process权限,对该客户没有日志记载到更新日志中。这不影响标准日志文件!
TIMESTAMP = timestamp_value | DEFAULT
为该客户设置时间。如果你使用更新日志恢复行,这被用来得到原来的时间标记。
LAST_INSERT_ID = #
设置从LAST_INSERT_ID()返回的值。当你在更新一个表的命令中使用LAST_INSERT_ID()时,它存储在更新日志中。
INSERT_ID = #
设置当插入一个AUTO_INCREMENT值时,由INSERT命令使用的值。这主要与更新日志一起使用。  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics