📄 ndb.hpp
字号:
/* Copyright (C) 2003 MySQL AB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; version 2 of the License. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//** @mainpage NDB API Programmers' Guide This guide assumes a basic familiarity with MySQL Cluster concepts found on http://dev.mysql.com/doc/mysql/en/mysql-cluster.html. Some of the fundamental ones are also described in section @ref secConcepts. The NDB API is a MySQL Cluster application interface that implements transactions. The NDB API consists of the following fundamental classes: - Ndb_cluster_connection, representing a connection to a cluster, - Ndb is the main class, representing a connection to a database, - NdbTransaction represents a transaction, - NdbOperation represents an operation using a primary key, - NdbScanOperation represents an operation performing a full table scan. - NdbIndexOperation represents an operation using a unique hash index, - NdbIndexScanOperation represents an operation performing a scan using an ordered index, - NdbRecAttr represents an attribute value - NdbDictionary represents meta information about tables and attributes. In addition, the NDB API defines a structure NdbError, which contains the specification for an error. There are also some auxiliary classes, which are listed in the class hierarchy. The main structure of an application program is as follows: -# Connect to a cluster using the Ndb_cluster_connection object. -# Initiate a database connection by constructing and initialising one or more Ndb objects. -# Define and execute transactions using the NdbTransaction class. -# Delete Ndb objects. -# Terminate the connection to the cluster (terminate instance of Ndb_cluster_connection). The procedure for using transactions is as follows: -# Start transaction (instantiate an NdbTransaction object) -# Add and define operations associated with the transaction using instances of one or more of the NdbOperation, NdbScanOperation, NdbIndexOperation, and NdbIndexScanOperation classes -# Execute transaction (call NdbTransaction::execute()) The operation can be of two different types, <var>Commit</var> or <var>NoCommit</var>. If the operation is of type <var>NoCommit</var>, then the application program executes the operation part of a transaction, but without actually committing the transaction. After executing a <var>NoCommit</var> operation, the program can continue to add and define more operations to the transaction for later execution. If the operation is of type <var>Commit</var>, then the transaction is immediately committed. The transaction <em>must</em> be closed after it has been commited (event if commit fails), and no further addition or definition of operations for this transaction is allowed. @section secSync Synchronous Transactions Synchronous transactions are defined and executed as follows: -# Start (create) the transaction, which is referenced by an NdbTransaction object (typically created using Ndb::startTransaction()). At this point, the transaction is only being defined, and is not yet sent to the NDB kernel. -# Define operations and add them to the transaction, using one or more of - NdbTransaction::getNdbOperation() - NdbTransaction::getNdbScanOperation() - NdbTransaction::getNdbIndexOperation() - NdbTransaction::getNdbIndexScanOperation() along with the appropriate methods of the respective NdbOperation class (or one possiblt one or more of its subclasses). Note that the transaction has still not yet been sent to the NDB kernel. -# Execute the transaction, using the NdbTransaction::execute() method. -# Close the transaction (call Ndb::closeTransaction()). For an example of this process, see the program listing in @ref ndbapi_simple.cpp. To execute several parallel synchronous transactions, one can either use multiple Ndb objects in several threads, or start multiple application programs. @section secNdbOperations Operations A NdbTransaction consists of a list of operations, each of which is represented by an instance of NdbOperation, NdbScanOperation, NdbIndexOperation, or NdbIndexScanOperation. <h3>Single row operations</h3> After the operation is created using NdbTransaction::getNdbOperation() (or NdbTransaction::getNdbIndexOperation()), it is defined in the following three steps: -# Define the standard operation type, using NdbOperation::readTuple() -# Specify search conditions, using NdbOperation::equal() -# Specify attribute actions, using NdbOperation::getValue() Here are two brief examples illustrating this process. For the sake of brevity, we omit error handling. This first example uses an NdbOperation: @code // 1. Retrieve table object myTable= myDict->getTable("MYTABLENAME"); // 2. Create myOperation= myTransaction->getNdbOperation(myTable); // 3. Define type of operation and lock mode myOperation->readTuple(NdbOperation::LM_Read); // 4. Specify Search Conditions myOperation->equal("ATTR1", i); // 5. Attribute Actions myRecAttr= myOperation->getValue("ATTR2", NULL); @endcode For additional examples of this sort, see @ref ndbapi_simple.cpp. The second example uses an NdbIndexOperation: @code // 1. Retrieve index object myIndex= myDict->getIndex("MYINDEX", "MYTABLENAME"); // 2. Create myOperation= myTransaction->getNdbIndexOperation(myIndex); // 3. Define type of operation and lock mode myOperation->readTuple(NdbOperation::LM_Read); // 4. Specify Search Conditions myOperation->equal("ATTR1", i); // 5. Attribute Actions myRecAttr = myOperation->getValue("ATTR2", NULL); @endcode Another example of this second type can be found in @ref ndbapi_simple_index.cpp. We will now discuss in somewhat greater detail each step involved in the creation and use of synchronous transactions. <h4>Step 1: Define single row operation type</h4> The following operation types are supported: -# NdbOperation::insertTuple() : inserts a non-existing tuple -# NdbOperation::writeTuple() : updates an existing tuple if is exists, otherwise inserts a new tuple -# NdbOperation::updateTuple() : updates an existing tuple -# NdbOperation::deleteTuple() : deletes an existing tuple -# NdbOperation::readTuple() : reads an existing tuple with specified lock mode All of these operations operate on the unique tuple key. (When NdbIndexOperation is used then all of these operations operate on a defined unique hash index.) @note If you want to define multiple operations within the same transaction, then you need to call NdbTransaction::getNdbOperation() or NdbTransaction::getNdbIndexOperation() for each operation. <h4>Step 2: Specify Search Conditions</h4> The search condition is used to select tuples. Search conditions are set using NdbOperation::equal(). <h4>Step 3: Specify Attribute Actions</h4> Next, it is necessary to determine which attributes should be read or updated. It is important to remember that: - Deletes can neither read nor set values, but only delete them - Reads can only read values - Updates can only set values Normally the attribute is identified by name, but it is also possible to use the attribute's identity to determine the attribute. NdbOperation::getValue() returns an NdbRecAttr object containing the read value. To obtain the actual value, one of two methods can be used; the application can either - use its own memory (passed through a pointer aValue) to NdbOperation::getValue(), or - receive the attribute value in an NdbRecAttr object allocated by the NDB API. The NdbRecAttr object is released when Ndb::closeTransaction() is called. Thus, the application cannot reference this object following any subsequent call to Ndb::closeTransaction(). Attempting to read data from an NdbRecAttr object before calling NdbTransaction::execute() yields an undefined result. @subsection secScan Scan Operations Scans are roughly the equivalent of SQL cursors, providing a means to preform high-speed row processing. A scan can be performed on either a table (using @ref NdbScanOperation) or an ordered index (by means of an @ref NdbIndexScanOperation). Scan operations are characterised by the following: - They can perform only reads (shared, exclusive or dirty) - They can potentially work with multiple rows - They can be used to update or delete multiple rows - They can operate on several nodes in parallel After the operation is created using NdbTransaction::getNdbScanOperation() (or NdbTransaction::getNdbIndexScanOperation()), it is carried out in the following three steps: -# Define the standard operation type, using NdbScanOperation::readTuples() -# Specify search conditions, using @ref NdbScanFilter and/or @ref NdbIndexScanOperation::setBound() -# Specify attribute actions, using NdbOperation::getValue() -# Executing the transaction, using NdbTransaction::execute() -# Traversing the result set by means of succssive calls to NdbScanOperation::nextResult() Here are two brief examples illustrating this process. Once again, in order to keep things relatively short and simple, we will forego any error handling. This first example performs a table scan, using an NdbScanOperation: @code // 1. Retrieve table object myTable= myDict->getTable("MYTABLENAME"); // 2. Create myOperation= myTransaction->getNdbScanOperation(myTable); // 3. Define type of operation and lock mode myOperation->readTuples(NdbOperation::LM_Read); // 4. Specify Search Conditions NdbScanFilter sf(myOperation); sf.begin(NdbScanFilter::OR); sf.eq(0, i); // Return rows with column 0 equal to i or sf.eq(1, i+1); // column 1 equal to (i+1) sf.end(); // 5. Attribute Actions myRecAttr= myOperation->getValue("ATTR2", NULL); @endcode Our second example uses an NdbIndexScanOperation to perform an index scan: @code // 1. Retrieve index object myIndex= myDict->getIndex("MYORDEREDINDEX", "MYTABLENAME"); // 2. Create myOperation= myTransaction->getNdbIndexScanOperation(myIndex); // 3. Define type of operation and lock mode myOperation->readTuples(NdbOperation::LM_Read); // 4. Specify Search Conditions // All rows with ATTR1 between i and (i+1) myOperation->setBound("ATTR1", NdbIndexScanOperation::BoundGE, i); myOperation->setBound("ATTR1", NdbIndexScanOperation::BoundLE, i+1); // 5. Attribute Actions myRecAttr = MyOperation->getValue("ATTR2", NULL); @endcode Some additional discussion of each step required to perform a scan follows: <h4>Step 1: Define Scan Operation Type</h4> It is important to remember that only a single operation is supported for each scan operation (@ref NdbScanOperation::readTuples() or @ref NdbIndexScanOperation::readTuples()). @note If you want to define multiple scan operations within the same transaction, then you need to call NdbTransaction::getNdbScanOperation() or NdbTransaction::getNdbIndexScanOperation() separately for <b>each</b> operation. <h4>Step 2: Specify Search Conditions</h4> The search condition is used to select tuples. If no search condition is specified, the scan will return all rows in the table. The search condition can be an @ref NdbScanFilter (which can be used on both @ref NdbScanOperation and @ref NdbIndexScanOperation) or bounds which can only be used on index scans (@ref NdbIndexScanOperation::setBound()). An index scan can use both NdbScanFilter and bounds. @note When NdbScanFilter is used, each row is examined, whether or not it is actually returned. However, when using bounds, only rows within the bounds will be examined. <h4>Step 3: Specify Attribute Actions</h4> Next, it is necessary to define which attributes should be read. As with transaction attributes, scan attributes are defined by name but it is also possible to use the attributes' identities to define attributes. As previously discussed (see @ref secSync), the value read is returned as an NdbRecAttr object by the NdbOperation::getValue() method. <h3>Using Scan to Update/Delete</h3> Scanning can also be used to update or delete rows. This is performed by -# Scanning using exclusive locks (using NdbOperation::LM_Exclusive) -# When iterating through the result set, for each row optionally calling either NdbScanOperation::updateCurrentTuple() or NdbScanOperation::deleteCurrentTuple() -# (If performing NdbScanOperation::updateCurrentTuple():) Setting new values for records simply by using @ref NdbOperation::setValue(). NdbOperation::equal() should <em>not</em> be called in such cases, as the primary key is retrieved from the scan. @note The actual update or delete will not be performed until the next call to NdbTransaction::execute(), just as with single row operations.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -