MySQL NDB Cluster 8.1 手冊
MySQL NDB Cluster 8.0 手冊
NDB Cluster 內部手冊
執行接下來幾個章節中的範例,軟體需求如下:
可運作的 Node.js 安裝
ndb
和mysql-js
配接器的可運作安裝mysql-js
配接器也需要來自 https://github.com/felixge/node-mysql/ 的node-mysql
驅動程式的可運作安裝。
第 5.2 節,「安裝 JavaScript 連接器」,說明這三個需求的安裝過程。
範例資料庫、表格和資料。 所有範例都使用名為 tweet
的範例表格,位於 test
資料庫中。此表格的定義如下 CREATE TABLE
陳述式
CREATE TABLE IF NOT EXISTS tweet (
id CHAR(36) NOT NULL PRIMARY KEY,
author VARCHAR(20),
message VARCHAR(140),
date_created TIMESTAMP,
KEY idx_btree_date_created (date_created),
KEY idx_btree_author(author)
)
ENGINE=NDB;
可以透過在 mysql 用戶端中執行隨附的 SQL 指令碼 create.sql
來建立 tweet
表格。您可以在系統 shell 中叫用 mysql 來執行此操作,如下所示
$> mysql < create.sql
所有範例也使用檔案 lib.js
中定義的兩個模組,其內容在此重現
# FILE: lib.js
"use strict";
var udebug = unified_debug.getLogger("samples/lib.js");
var exec = require("child_process").exec;
var SQL = {};
/* Pseudo random UUID generator */
var randomUUID = function() {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
var r = Math.random()*16|0, v = c == 'x' ? r : (r&0x3|0x8);
return v.toString(16);
});
};
/* Tweet domain object model */
var Tweet = function(author, message) {
this.id = randomUUID();
this.date_created = new Date();
this.author = author;
this.message = message;
};
/* SQL DDL Utilities */
var runSQL = function(sqlPath, source, callback) {
function childProcess(error, stdout, stderr) {
udebug.log('harness runSQL process completed.');
udebug.log(source + ' stdout: ' + stdout);
udebug.log(source + ' stderr: ' + stderr);
if (error !== null) {
console.log(source + 'exec error: ' + error);
} else {
udebug.log(source + ' exec OK');
}
if(callback) {
callback(error);
}
}
var p = mysql_conn_properties;
var cmd = 'mysql';
if(p) {
if(p.mysql_socket) { cmd += " --socket=" + p.mysql_socket; }
else if(p.mysql_port) { cmd += " --port=" + p.mysql_port; }
if(p.mysql_host) { cmd += " -h " + p.mysql_host; }
if(p.mysql_user) { cmd += " -u " + p.mysql_user; }
if(p.mysql_password) { cmd += " --password=" + p.mysql_password; }
}
cmd += ' <' + sqlPath;
udebug.log('harness runSQL forking process...');
var child = exec(cmd, childProcess);
};
SQL.create = function(suite, callback) {
var sqlPath = path.join(suite.path, 'create.sql');
udebug.log_detail("createSQL path: " + sqlPath);
runSQL(sqlPath, 'createSQL', callback);
};
SQL.drop = function(suite, callback) {
var sqlPath = path.join(suite.path, 'drop.sql');
udebug.log_detail("dropSQL path: " + sqlPath);
runSQL(sqlPath, 'dropSQL', callback);
};
/* Exports from this module */
exports.SQL = SQL;
exports.Tweet = Tweet;
最後,用於隨機資料產生的模組包含在檔案 ndb_loader/lib/RandomData.js
中,如下所示
# FILE: RandomData.js
var assert = require("assert");
function RandomIntGenerator(min, max) {
assert(max > min);
var range = max - min;
this.next = function() {
var x = Math.floor(Math.random() * range);
return min + x;
};
}
function SequentialIntGenerator(startSeq) {
var seq = startSeq - 1;
this.next = function() {
seq += 1;
return seq;
};
}
function RandomFloatGenerator(min, max, prec, scale) {
assert(max > min);
this.next = function() {
var x = Math.random();
/* fixme! */
return 100 * x;
};
}
function RandomCharacterGenerator() {
var intGenerator = new RandomIntGenerator(32, 126);
this.next = function() {
return String.fromCharCode(intGenerator.next());
};
}
function RandomVarcharGenerator(length) {
var lengthGenerator = new RandomIntGenerator(0, length),
characterGenerator = new RandomCharacterGenerator();
this.next = function() {
var i = 0,
str = "",
len = lengthGenerator.next();
for(; i < len ; i++) str += characterGenerator.next();
return str;
}
}
function RandomCharGenerator(length) {
var characterGenerator = new RandomCharacterGenerator();
this.next = function() {
var i = 0,
str = "";
for(; i < length ; i++) str += characterGenerator.next();
return str;
};
}
function RandomDateGenerator() {
var generator = new RandomIntGenerator(0, Date.now());
this.next = function() {
return new Date(generator.next());
};
}
function RandomGeneratorForColumn(column) {
var g = {},
min, max, bits;
switch(column.columnType.toLocaleUpperCase()) {
case "TINYINT":
case "SMALLINT":
case "MEDIUMINT":
case "INT":
case "BIGINT":
if(column.isInPrimaryKey) {
g = new SequentialIntGenerator(0);
}
else {
bits = column.intSize * 8;
max = column.isUnsigned ? Math.pow(2,bits)-1 : Math.pow(2, bits-1);
min = column.isUnsigned ? 0 : 1 - max;
g = new RandomIntGenerator(min, max);
}
break;
case "FLOAT":
case "DOUBLE":
case "DECIMAL":
g = new RandomFloatGenerator(0, 100000); // fixme
break;
case "CHAR":
g = new RandomCharGenerator(column.length);
break;
case "VARCHAR":
g = new RandomVarcharGenerator(column.length);
break;
case "TIMESTAMP":
g = new RandomIntGenerator(0, Math.pow(2,32)-1);
break;
case "YEAR":
g = new RandomIntGenerator(1900, 2155);
break;
case "DATE":
case "TIME":
case "DATETIME":
g = new RandomDateGenerator();
break;
case "BLOB":
case "TEXT":
case "BIT":
case "BINARY":
case "VARBINARY":
default:
throw("UNSUPPORTED COLUMN TYPE " + column.columnType);
break;
}
return g;
}
function RandomRowGenerator(table) {
var i = 0,
generators = [];
for(; i < table.columns.length ; i++) {
generators[i] = RandomGeneratorForColumn(table.columns[i]);
}
this.newRow = function() {
var n, col, row = {};
for(n = 0; n < table.columns.length ; n++) {
col = table.columns[n];
row[col.name] = generators[n].next();
}
return row;
};
}
exports.RandomRowGenerator = RandomRowGenerator;
exports.RandomGeneratorForColumn = RandomGeneratorForColumn;