与没有使用簇的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簇存储引擎将自动生成隐含的主键。(注释:该隐含 键也将占用空间,就像任何其他的表索引一样。由于没有足够的内存来容纳这些自动创建的键,出现问题并不罕见)。