文档首页
MySQL 9.0 参考手册
相关文档 下载本手册
PDF (US Ltr) - 40.0Mb
PDF (A4) - 40.1Mb
手册页 (TGZ) - 258.2Kb
手册页 (Zip) - 365.3Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 9.0 参考手册  /  ...  /  带有表和数据的 NDB 集群示例

25.3.5 带有表和数据的 NDB 集群示例

注意

本节信息适用于在 Unix 和 Windows 平台上运行的 NDB 集群。

在 NDB 集群中操作数据库表和数据与在标准 MySQL 中操作没有太大区别。需要牢记以下两点

  • 要使表在集群中进行复制,它必须使用 NDBCLUSTER 存储引擎。要指定此引擎,在创建表时使用 ENGINE=NDBCLUSTERENGINE=NDB 选项

    CREATE TABLE tbl_name (col_name column_definitions) ENGINE=NDBCLUSTER;

    或者,对于使用其他存储引擎的现有表,可以使用 ALTER TABLE 将表更改为使用 NDBCLUSTER

    ALTER TABLE tbl_name ENGINE=NDBCLUSTER;
  • 每个 NDBCLUSTER 表都有一个主键。如果用户在创建表时没有定义主键,则 NDBCLUSTER 存储引擎会自动生成一个隐藏的主键。这样的主键会占用空间,就像其他表索引一样。(由于内存不足而无法容纳这些自动创建的索引,这种情况并不少见。)

如果您要使用 mysqldump 的输出将表从现有数据库导入,可以在文本编辑器中打开 SQL 脚本,并将 ENGINE 选项添加到任何表创建语句,或者替换任何现有的 ENGINE 选项。假设您在另一个不支持 NDB 集群的 MySQL 服务器上拥有 world 示例数据库,并且您想要导出 City

$> 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 为此表使用 NDBCLUSTER 存储引擎。这可以通过两种方式实现。其中一种是在将表导入集群数据库 之前 修改表定义。以 City 表为例,修改定义的 ENGINE 选项,如下所示

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);
(remaining INSERT statements omitted)

必须针对要作为集群数据库一部分的每个表的定义执行此操作。完成此操作的最简单方法是对包含定义的文件执行搜索和替换,并将所有 ENGINE=engine_name 实例替换为 ENGINE=NDBCLUSTER。如果您不想修改文件,可以使用未修改的文件创建表,然后使用 ALTER TABLE 更改其存储引擎。本节后面将详细说明具体步骤。

假设您已经在集群的 SQL 节点上创建了一个名为 world 的数据库,那么可以使用 mysql 命令行客户端读取 city_table.sql,并以通常的方式创建和填充相应的表

$> mysql world < city_table.sql

务必牢记,上述命令必须在运行 SQL 节点的主机上执行(在本例中,是在具有 IP 地址 198.51.100.20 的机器上)。

要创建 SQL 节点上整个 world 数据库的副本,请在非集群服务器上使用 mysqldump 将数据库导出到名为 world.sql 的文件(例如,在 /tmp 目录中)。然后按上述说明修改表定义,并将文件导入集群的 SQL 节点,如下所示

$> mysql world < /tmp/world.sql

如果您将文件保存到其他位置,请相应地调整上述说明。

在 SQL 节点上运行 SELECT 查询与在任何其他 MySQL 服务器实例上运行查询没有区别。要从命令行运行查询,首先需要以通常的方式登录到 MySQL 监视器(在 Enter password: 提示符下指定 root 密码)

$> 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: 9.0.0-ndb-9.0.0

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

我们只使用 MySQL 服务器的 root 帐户,并假设您已按照安装 MySQL 服务器的标准安全预防措施进行了操作,包括设置强 root 密码。有关更多信息,请参见 第 2.9.4 节,“保护初始 MySQL 帐户”

值得注意的是,NDB 集群节点在相互访问时 使用 MySQL 权限系统。设置或更改 MySQL 用户帐户(包括 root 帐户)只会影响访问 SQL 节点的应用程序,而不会影响节点之间的交互。有关更多信息,请参见 第 25.6.21.2 节,“NDB 集群和 MySQL 权限”

如果您在导入 SQL 脚本之前没有修改表定义中的 ENGINE 子句,则此时应运行以下语句

mysql> USE world;
mysql> ALTER TABLE City ENGINE=NDBCLUSTER;
mysql> ALTER TABLE Country ENGINE=NDBCLUSTER;
mysql> ALTER TABLE CountryLanguage ENGINE=NDBCLUSTER;

选择数据库并对该数据库中的表运行 SELECT 查询也是以通常的方式完成的,退出 MySQL 监视器也是如此

mysql> USE world;
mysql> SELECT Name, Population FROM City ORDER BY Population DESC LIMIT 5;
+-----------+------------+
| Name      | Population |
+-----------+------------+
| Bombay    |   10500000 |
| Seoul     |    9981619 |
| São Paulo |    9968485 |
| Shanghai  |    9696300 |
| Jakarta   |    9604900 |
+-----------+------------+
5 rows in set (0.34 sec)

mysql> \q
Bye

$>

使用 MySQL 的应用程序可以使用标准 API 访问 NDB 表。务必记住,您的应用程序必须访问 SQL 节点,而不是管理节点或数据节点。这个简短的示例演示了如何使用网络上其他地方的 Web 服务器上运行的 PHP 5.X mysqli 扩展执行上面显示的 SELECT 语句

<!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('198.51.100.20', 'root', 'root_password', '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 连接器执行数据定义和操作任务,就像您通常在 MySQL 中执行这些任务一样。