• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • 具有表和数据的NDB群集示例

    注意

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

    在NDB Cluster中使用数据库表和数据与在标准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选项。假设您world在另一台不支持NDB群集的MySQL服务器上具有示例数据库,并且想要导出该City表:

    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 DEFAULT CHARSET=latin1;
    
    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 DEFAULT CHARSET=latin1;
    
    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)
    

    必须对要成为集群数据库一部分的每个表进行定义。做到这一点最简单的方法是做一个搜索和替换包含定义和替换的所有实例的文件或用。如果您不想修改文件,则可以使用未修改的文件来创建表,然后使用来更改它们的存储引擎。详细信息将在本节后面给出。TYPE=engine_nameENGINE=engine_nameENGINE=NDBCLUSTERALTER TABLE

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

    shell>mysql world < city_table.sql
    

    请记住,必须在运行SQL节点的主机上(在这种情况下,在IP地址为的机器上198.51.100.20)执行前面的命令,这一点非常重要。

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

    shell>mysql world < /tmp/world.sql
    

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

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

    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: 8.0.20-ndb-8.0.20
    
    Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
    
    mysql>
    

    我们仅使用MySQL服务器的root帐户,并假定您已遵循安装MySQL服务器的标准安全预防措施,包括设置强root密码。有关更多信息,请参见“保护初始MySQL帐户”。

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

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

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

    选择数据库并对数据库中的表运行SELECT查询也可以通过通常的方式完成,就像退出MySQL Monitor一样:

    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
    
    shell>
    

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

    <!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一样。