与没有使用簇的MySQL相比,在MySQL簇内操作数据的方式没有太大的区别。执行这类操作时应记住两点:
· 表必须用ENGINE=NDB或ENGINE=NDBCLUSTER选项创建,或用ALTER TABLE选项更改,以使用NDB簇存储引擎在簇内复制它们。如果使用mysqldump的输出从已有数据库导入表,可在文本编辑器中打开SQL脚本,并将该选项添加到任何表创建语句,或用这类选项之一替换任何已有的ENGINE(或TYPE)选项。例如,假定在另一个MySQL服务器(不支持MySQL簇)上有样本世界数据库,而且你打算导出城市表的定义:
· shell> mysqldump --add-drop-table world City > city_table.sql
在所得的city_table.sql文件中,将包含这条表创建语句(以及导入表数据所需的INSERT语句):
DROP TABLE IF EXISTS City;
CREATE TABLE City (
ID int(11) NOT NULL auto_increment,
Name char(35) NOT NULL default '',
CountryCode char(3) NOT NULL default '',
District char(20) NOT NULL default '',
Population int(11) NOT NULL default '0',
PRIMARY KEY (ID)
) ENGINE=MyISAM;
INSERT INTO City VALUES (1,'Kabul','AFG','Kabol',1780000);
INSERT INTO City VALUES (2,'Qandahar','AFG','Qandahar',237500);
INSERT INTO City VALUES (3,'Herat','AFG','Herat',186800);
# (remaining INSERT statements omitted)
需要确认MySQL为该表使用了NDB存储引擎。有两种完成该任务的方法。其中一种方法是,在将表导入簇数据库之前更改其定义,使其类似于(仍使用“城市”作为示例):
DROP TABLE IF EXISTS City;
CREATE TABLE City (
ID int(11) NOT NULL auto_increment,
Name char(35) NOT NULL default '',
CountryCode char(3) NOT NULL default '',
District char(20) NOT NULL default '',
Population int(11) NOT NULL default '0',
PRIMARY KEY (ID)
) ENGINE=NDBCLUSTER;
INSERT INTO City VALUES (1,'Kabul','AFG','Kabol',1780000);
INSERT INTO City VALUES (2,'Qandahar','AFG','Qandahar',237500);
INSERT INTO City VALUES (3,'Herat','AFG','Herat',186800);
# (etc.)
对于将成为簇数据库组成部份的每个表,均需要为其定义执行上述操作。完成该任务的最简单方法是,简单地在world.sql文件上执行“查找-替换”,并用ENGINE=NDBCLUSTER替换所有的TYPE=MyISAM实例。如果你不打算更改该文件,也可使用ALTER TABLE。详情请参见下面的介绍。
假定你已在簇的SQL节点上创建了名为“world”的数据库,随后可使用mysql命令行客户端读取city_table.sql,并按通常方式创建和填充对应的表:
shell> mysql world < city_table.sql
请记住,上述命令必须在运行SQL节点的主机上执行,这点十分重要。对于本例,应在IP地址为192.168.0.20的机器上执行。
要想在SQL节点上创建世界数据库的副本,请将文件保存到/usr/local/mysql/data,然后运行:
shell> cd /usr/local/mysql/data
shell> mysql world < world.sql
当然,SQL脚本必须能被mysql系统用户读取。如果将文件保存到了不同的目录下,请作相应的调整。
注意,在MySQL 5.1中,NDB簇不支持自动发现数据库的功能,这点很重要(请参见17.8节,“MySQL簇的已知限制”)。这意味着,一旦在一个数据节点上创建了世界(world)数据库和它的表,在簇中的每个SQL节点上还需要发出命令CREATE DATABASE world(从MySQL 5.0.2开始,可以使用CREATE SCHEMA world取而代之),后跟FLUSH TABLES。这样,节点就能识别数据库并读取其表定义。
在SQL节点上运行SELECT查询与在MySQL服务器的任何其他实例上运行查询没有区别。要想从命令行运行查询,首先应按照通常方式登录到MySQL监视器:
shell> mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1 to server version: 5.1.2-alpha
键入’help;’或’\h’获取帮助。键入’\c’清空缓冲区。
mysql>
如果在导入MySQL脚本之前未更改表定义中的ENGINE=子句,应在此时运行下述命令:
mysql> USE world;
mysql> ALTER TABLE City ENGINE=NDBCLUSTER;
mysql> ALTER TABLE Country ENGINE=NDBCLUSTER;
mysql> ALTER TABLE CountryLanguage ENGINE=NDBCLUSTER;
注意,在这里我们简单地使用了MySQL服务器密码为空的默认根用户账户。当然,在生产设置下,安装MySQL服务器时,总应遵守标准的安全方法措施,包括设置牢靠的根用户密码,并为用户创建具有完成任务所需的权限的用户账户。关于这方面的更多信息,请参见5.7节,“MySQL访问权限系统”。
需要关注的是,当簇节点彼此访问时不使用MySQL的权限系统,设置或更改MySQL用户账户(包括根用户账户)不影响节点之间的交互,它们仅对访问SQL节点的应用程序有效。
能够以通常的方式选择数据库,并对表执行SELECT查询,就像退出MySQL监视器一样:
mysql> USE world;
mysql> SELECT Name, Population FROM City ORDER BY Population DESC LIMIT 5;
+-----------+------------+
| 名称 | 人口 |
+-----------+------------+
| 孟买 | 10500000 |
| 汉城 | 9981619 |
| 圣保罗 | 9968485 |
| 上海 | 9696300 |
| 雅加达 | 9604900 |
+-----------+------------+
5 rows in set (0.34 sec)
mysql> \q
Bye
shell>
使用MySQL的应用程序能够使用标准的API。重要的是应记住,你的应用程序必须访问SQL节点,而不是MGM或存储节点。在下面的简单示例中,介绍了使用PHP 5的mysqli扩展(运行在位于网络中其他位置的Web服务器上)执行相同查询的方法:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=iso-8859-1">
<title>SIMPLE mysqli SELECT</title>
</head>
<body>
<?php
# connect to SQL node:
$link = new mysqli('192.168.0.20', 'root', '', 'world');
# parameters for mysqli constructor are:
# host, user, password, database
if( mysqli_connect_errno() )
die("Connect failed: " . mysqli_connect_error());
$query = "SELECT Name, Population
FROM City
ORDER BY Population DESC
LIMIT 5";
# if no errors...
if( $result = $link->query($query) )
{
?>
<table border="1" width="40%" cellpadding="4" cellspacing ="1">
<tbody>
<tr>
<th width="10%">City</th>
<th>Population</th>
</tr>
<?
# then display the results...
while($row = $result->fetch_object())
printf(<tr>\n <td align=\"center\">%s</td><td>%d</td>\n</tr>\n",
$row->Name, $row->Population);
?>
</tbody
</table>
<?
# ...and verify the number of rows that were retrieved
printf("<p>Affected rows: %d</p>\n", $link->affected_rows);
}
else
# otherwise, tell us what went wrong
echo mysqli_error();
# free the result set and the mysqli connection object
$result->close();
$link->close();
?>
</body>
</html>
我们假定运行在Web服务器上的进程能够访问SQL节点的IP地址。
采用类似的风格,可以使用MySQL C API、Perl-DBI、Python-mysql、或MySQL AB自己的连接器来执行数据定义和操控任务,就像正常使用MySQL那样。
· 另外还请记住,每个NDB表必须有一个主键。如果在创建表时用户未定义主键,NDB簇存储引擎将自动生成隐含的主键。(注释:该隐含 键也将占用空间,就像任何其他的表索引一样。由于没有足够的内存来容纳这些自动创建的键,出现问题并不罕见)。