既存の MySQL スキーマまたはアプリケーションを daemon_memcached
プラグインを使用するように適応させる場合は、memcached アプリケーションの次の側面を考慮してください:
memcached キーに空白や改行を含めることはできません。これらの文字は ASCII プロトコルでセパレータとして使用されるためです。 スペースを含む検索値を使用する場合は、
add()
、set()
、get()
, などの呼び出しでこれらをキーとして使用する前に、スペースのない値に変換またはハッシュします。 理論上、これらの文字はバイナリプロトコルを使用するプログラム内の鍵で使用できますが、広範囲のクライアントとの互換性を確保するために、鍵で使用される文字を制限するようにしてください。-
InnoDB
テーブルに短い数値の primary key カラムがある場合は、整数を文字列値に変換して、memcached の一意の参照キーとして使用します。 memcached サーバーが複数のアプリケーションに使用されている場合、または複数のInnoDB
テーブルで使用されている場合は、一意になるように名前を変更することを検討してください。 たとえば、数値の前にテーブル名またはデータベース名とテーブル名を付加します。注記daemon_memcached
プラグインは、INTEGER
が主キーとして定義されているマップ済InnoDB
テーブルでの挿入および読取りをサポートしています。 memcached を使用してクエリーまたは格納されたデータには、パーティションテーブルを使用できません。
-
memcached プロトコルは数値を文字列として渡します。
SUM()
やAVG()
などの SQL 関数で使用できるカウンタを実装するために、基礎となるInnoDB
テーブルに数値を格納するには、次のようにします:予想される最大数のすべての桁 (さらに該当する場合はマイナス符号、小数点またはその両方に対する追加の文字) を保持するために十分な文字がある
VARCHAR
カラムを使用します。-
カラム値を使用して算術を実行するクエリーでは、
CAST()
関数を使用して、値を文字列から整数または他の数値型に変換します。 例:# Alphabetic entries are returned as zero. SELECT CAST(c2 as unsigned integer) FROM demo_test; # Since there could be numeric values of 0, can't disqualify them. # Test the string values to find the ones that are integers, and average only those. SELECT AVG(cast(c2 as unsigned integer)) FROM demo_test WHERE c2 BETWEEN '0' and '9999999999'; # Views let you hide the complexity of queries. The results are already converted; # no need to repeat conversion functions and WHERE clauses each time. CREATE VIEW numbers AS SELECT c1 KEY, CAST(c2 AS UNSIGNED INTEGER) val FROM demo_test WHERE c2 BETWEEN '0' and '9999999999'; SELECT SUM(val) FROM numbers;
注記結果セット内のアルファベット値は、
CAST()
のコールによって 0 に変換されます。 結果セット内の行数に依存するAVG()
などの関数を使用する場合は、数値以外の値を除外するためのWHERE
句を含めます。
キーとして使用される
InnoDB
カラムの値が 250 バイトを超える可能性がある場合は、250 バイト未満にハッシュします。-
daemon_memcached
プラグインで既存のテーブルを使用するには、innodb_memcache.containers
テーブルにそのテーブルのエントリを定義します。 このテーブルをすべての memcached リクエストのデフォルトにするには、name
カラムにdefault
の値を指定し、MySQL サーバーを再起動して変更を有効にします。 異なるクラスの memcached データに複数のテーブルを使用する場合は、選択したname
値を使用してinnodb_memcache.containers
テーブルに複数のエントリを設定し、アプリケーション内でget @@
またはname
set @@
の形式で memcached リクエストを発行して、後続の memcached リクエストに使用するテーブルを指定します。name
事前定義された
test.demo_test
テーブル以外のテーブルを使用する例については、例15.13「InnoDB memcached アプリケーションでの独自のテーブルの使用」を参照してください。 必要なテーブルレイアウトについては、セクション15.20.8「InnoDB memcached プラグインの内部」 を参照してください。 -
memcached キーと値のペアで複数の
InnoDB
テーブルのカラム値を使用するには、InnoDB
テーブルのinnodb_memcache.containers
エントリのvalue_columns
フィールドに、カンマ、セミコロン、空白またはパイプ文字で区切られたカラム名を指定します。 たとえば、value_columns
フィールドにcol1,col2,col3
またはcol1|col2|col3
を指定します。memcached
add
またはset
コールに文字列を渡す前に、パイプ文字をセパレータとして使用して、カラム値を単一の文字列に連結します。 文字列は、正しいカラムに自動的に解凍されます。 各get
コールは、パイプ文字で区切られたカラム値を含む単一の文字列を戻します。 適切なアプリケーション言語構文を使用して、値を解凍できます。
例 15.13 InnoDB memcached アプリケーションでの独自のテーブルの使用
この例では、データ操作に memcached
を使用するサンプル Python アプリケーションで独自のテーブルを使用する方法を示します。
この例では、セクション15.20.3「InnoDB memcached プラグインの設定」 の説明に従って daemon_memcached
プラグインがインストールされていることを前提としています。 また、python-memcache
モジュールを使用する Python スクリプトを実行するようにシステムが構成されていることも前提としています。
-
母集団、地域およびドライバ側のデータを含む国情報を格納する
multicol
テーブルを作成します (右側の場合は'R'
、左側の場合は'L'
)。mysql> USE test; mysql> CREATE TABLE `multicol` ( `country` varchar(128) NOT NULL DEFAULT '', `population` varchar(10) DEFAULT NULL, `area_sq_km` varchar(9) DEFAULT NULL, `drive_side` varchar(1) DEFAULT NULL, `c3` int(11) DEFAULT NULL, `c4` bigint(20) unsigned DEFAULT NULL, `c5` int(11) DEFAULT NULL, PRIMARY KEY (`country`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
-
daemon_memcached
プラグインがmulticol
テーブルにアクセスできるように、innodb_memcache.containers
テーブルにレコードを挿入します。mysql> INSERT INTO innodb_memcache.containers (name,db_schema,db_table,key_columns,value_columns,flags,cas_column, expire_time_column,unique_idx_name_on_key) VALUES ('bbb','test','multicol','country','population,area_sq_km,drive_side', 'c3','c4','c5','PRIMARY'); mysql> COMMIT;
-
multicol
テーブルのinnodb_memcache.containers
レコードは、'bbb'
のname
値 (テーブル識別子) を指定します。注記すべての memcached アプリケーションに単一の
InnoDB
テーブルが使用されている場合、@@
テーブル記法を使用してテーブルを切り替えるのを避けるために、name
値をdefault
に設定できます。 db_schema
カラムは、multicol
テーブルが存在するデータベースの名前であるtest
に設定されます。db_table
カラムは、InnoDB
テーブルの名前であるmulticol
に設定されます。key_columns
は、一意のcountry
カラムに設定されます。country
カラムは、multicol
テーブル定義で主キーとして定義されます。複合データ値を保持する単一の
InnoDB
テーブルのカラムではなく、データは 3 つのテーブルのカラム (population
、area_sq_km
およびdrive_side
) に分割されます。 複数の値カラムに対応するには、value_columns
フィールドにカンマ区切りのカラムリストを指定します。value_columns
フィールドに定義されているカラムは、値の格納または取得時に使用されるカラムです。flags
、expire_time
およびcas_column
の各フィールドの値は、demo.test
サンプルテーブルで使用されている値に基づきます。 これらのフィールドは通常、daemon_memcached
プラグインを使用するアプリケーションでは重要ではありません。これは、MySQL がデータの同期を維持し、データの期限切れや失効を心配する必要がないためです。unique_idx_name_on_key
フィールドがPRIMARY
に設定され、multicol
テーブルの一意のcountry
カラムに定義されているプライマリインデックスを参照します。
-
-
サンプル Python アプリケーションをファイルにコピーします。 この例では、サンプルスクリプトが
multicol.py
という名前のファイルにコピーされます。サンプル Python アプリケーションは、
daemon_memcached
プラグインを介してInnoDB
テーブルにアクセスする方法を示す、multicol
テーブルにデータを挿入し、すべてのキーのデータを取得します。import sys, os import memcache def connect_to_memcached(): memc = memcache.Client(['127.0.0.1:11211'], debug=0); print "Connected to memcached." return memc def banner(message): print print "=" * len(message) print message print "=" * len(message) country_data = [ ("Canada","34820000","9984670","R"), ("USA","314242000","9826675","R"), ("Ireland","6399152","84421","L"), ("UK","62262000","243610","L"), ("Mexico","113910608","1972550","R"), ("Denmark","5543453","43094","R"), ("Norway","5002942","385252","R"), ("UAE","8264070","83600","R"), ("India","1210193422","3287263","L"), ("China","1347350000","9640821","R"), ] def switch_table(memc,table): key = "@@" + table print "Switching default table to '" + table + "' by issuing GET for '" + key + "'." result = memc.get(key) def insert_country_data(memc): banner("Inserting initial data via memcached interface") for item in country_data: country = item[0] population = item[1] area = item[2] drive_side = item[3] key = country value = "|".join([population,area,drive_side]) print "Key = " + key print "Value = " + value if memc.add(key,value): print "Added new key, value pair." else: print "Updating value for existing key." memc.set(key,value) def query_country_data(memc): banner("Retrieving data for all keys (country names)") for item in country_data: key = item[0] result = memc.get(key) print "Here is the result retrieved from the database for key " + key + ":" print result (m_population, m_area, m_drive_side) = result.split("|") print "Unpacked population value: " + m_population print "Unpacked area value : " + m_area print "Unpacked drive side value: " + m_drive_side if __name__ == '__main__': memc = connect_to_memcached() switch_table(memc,"bbb") insert_country_data(memc) query_country_data(memc) sys.exit(0)
サンプル Python アプリケーションのノート:
データ操作は memcached インタフェースを介して実行されるため、アプリケーションの実行にデータベース認可は必要ありません。 必要な情報は、memcached デーモンがリスニングするローカルシステム上のポート番号のみです。
-
アプリケーションで
multicol
テーブルが使用されるようにするために、switch_table()
関数がコールされ、@@
テーブル記法を使用してダミーのget
またはset
リクエストが実行されます。 リクエストのname
値は、innodb_memcache.containers.name
フィールドで定義されているmulticol
テーブル識別子であるbbb
です。実際のアプリケーションでは、より説明的な
name
値を使用できます。 この例は、get @@...
リクエストでテーブル名ではなくテーブル識別子が指定されていることを示しています。 データの挿入およびクエリーに使用されるユーティリティ関数は、
add
またはset
リクエストを使用して MySQL にデータを送信するために Python データ構造をパイプ区切りの値に変換する方法、およびget
リクエストによって返されるパイプ区切りの値を解凍する方法を示しています。 この追加処理は、単一の memcached 値を複数の MySQL テーブルのカラムにマップする場合にのみ必要です。
-
サンプル Python アプリケーションを実行します。
shell> python multicol.py
成功した場合、サンプルアプリケーションは次の出力を返します:
Connected to memcached. Switching default table to 'bbb' by issuing GET for '@@bbb'. ============================================== Inserting initial data via memcached interface ============================================== Key = Canada Value = 34820000|9984670|R Added new key, value pair. Key = USA Value = 314242000|9826675|R Added new key, value pair. Key = Ireland Value = 6399152|84421|L Added new key, value pair. Key = UK Value = 62262000|243610|L Added new key, value pair. Key = Mexico Value = 113910608|1972550|R Added new key, value pair. Key = Denmark Value = 5543453|43094|R Added new key, value pair. Key = Norway Value = 5002942|385252|R Added new key, value pair. Key = UAE Value = 8264070|83600|R Added new key, value pair. Key = India Value = 1210193422|3287263|L Added new key, value pair. Key = China Value = 1347350000|9640821|R Added new key, value pair. ============================================ Retrieving data for all keys (country names) ============================================ Here is the result retrieved from the database for key Canada: 34820000|9984670|R Unpacked population value: 34820000 Unpacked area value : 9984670 Unpacked drive side value: R Here is the result retrieved from the database for key USA: 314242000|9826675|R Unpacked population value: 314242000 Unpacked area value : 9826675 Unpacked drive side value: R Here is the result retrieved from the database for key Ireland: 6399152|84421|L Unpacked population value: 6399152 Unpacked area value : 84421 Unpacked drive side value: L Here is the result retrieved from the database for key UK: 62262000|243610|L Unpacked population value: 62262000 Unpacked area value : 243610 Unpacked drive side value: L Here is the result retrieved from the database for key Mexico: 113910608|1972550|R Unpacked population value: 113910608 Unpacked area value : 1972550 Unpacked drive side value: R Here is the result retrieved from the database for key Denmark: 5543453|43094|R Unpacked population value: 5543453 Unpacked area value : 43094 Unpacked drive side value: R Here is the result retrieved from the database for key Norway: 5002942|385252|R Unpacked population value: 5002942 Unpacked area value : 385252 Unpacked drive side value: R Here is the result retrieved from the database for key UAE: 8264070|83600|R Unpacked population value: 8264070 Unpacked area value : 83600 Unpacked drive side value: R Here is the result retrieved from the database for key India: 1210193422|3287263|L Unpacked population value: 1210193422 Unpacked area value : 3287263 Unpacked drive side value: L Here is the result retrieved from the database for key China: 1347350000|9640821|R Unpacked population value: 1347350000 Unpacked area value : 9640821 Unpacked drive side value: R
-
innodb_memcache.containers
テーブルをクエリーして、multicol
テーブルに対して前に挿入したレコードを表示します。 最初のレコードは、daemon_memcached
プラグインの初期設定時に作成されるdemo_test
テーブルのサンプルエントリです。 2 番目のレコードは、multicol
テーブルに挿入したエントリです。mysql> SELECT * FROM innodb_memcache.containers\G *************************** 1. row *************************** name: aaa db_schema: test db_table: demo_test key_columns: c1 value_columns: c2 flags: c3 cas_column: c4 expire_time_column: c5 unique_idx_name_on_key: PRIMARY *************************** 2. row *************************** name: bbb db_schema: test db_table: multicol key_columns: country value_columns: population,area_sq_km,drive_side flags: c3 cas_column: c4 expire_time_column: c5 unique_idx_name_on_key: PRIMARY
-
multicol
テーブルをクエリーして、サンプル Python アプリケーションによって挿入されたデータを表示します。 データは MySQL queries で使用でき、SQL またはアプリケーション (適切な MySQL Connector or API を使用) を介して同じデータにアクセスする方法を示します。mysql> SELECT * FROM test.multicol; +---------+------------+------------+------------+------+------+------+ | country | population | area_sq_km | drive_side | c3 | c4 | c5 | +---------+------------+------------+------------+------+------+------+ | Canada | 34820000 | 9984670 | R | 0 | 11 | 0 | | China | 1347350000 | 9640821 | R | 0 | 20 | 0 | | Denmark | 5543453 | 43094 | R | 0 | 16 | 0 | | India | 1210193422 | 3287263 | L | 0 | 19 | 0 | | Ireland | 6399152 | 84421 | L | 0 | 13 | 0 | | Mexico | 113910608 | 1972550 | R | 0 | 15 | 0 | | Norway | 5002942 | 385252 | R | 0 | 17 | 0 | | UAE | 8264070 | 83600 | R | 0 | 18 | 0 | | UK | 62262000 | 243610 | L | 0 | 14 | 0 | | USA | 314242000 | 9826675 | R | 0 | 12 | 0 | +---------+------------+------------+------------+------+------+------+
注記数値として扱われるカラムの長さを定義する場合は、必要な桁数、小数点、符号文字、先頭のゼロなどを保持するのに十分なサイズを常に許可してください。
VARCHAR
などの文字列カラムの Too-long 値は、意味のない数値を生成する可能性のある一部の文字を削除することによって切り捨てられます。 -
オプションで、memcached データを格納する
InnoDB
テーブルに対してレポートタイプのクエリーを実行します。country
キーカラムのみでなく、任意のカラムに対して計算およびテストを実行して、SQL クエリーを介してレポートを生成できます。 (次の例では、少数の国のデータのみを使用しているため、数字は説明のみを目的としています。) 次のクエリーは、人々が右側を運転する国の平均人口、および名前が 「U」 で始まる国の平均サイズを返します:mysql> SELECT AVG(population) FROM multicol WHERE drive_side = 'R'; +-------------------+ | avg(population) | +-------------------+ | 261304724.7142857 | +-------------------+ mysql> SELECT SUM(area_sq_km) FROM multicol WHERE country LIKE 'U%'; +-----------------+ | sum(area_sq_km) | +-----------------+ | 10153885 | +-----------------+
population
およびarea_sq_km
のカラムには強い型指定の数値データではなく文字データが格納されるため、AVG()
やSUM()
などの関数は、最初に各値を数値に変換することによって機能します。 このアプローチでは、<
や>
などの演算子に機能しないを使用します。たとえば、ORDER BY population DESC
などの句から想定されていない文字ベースの値9 > 1000
を比較する場合などです。 もっとも正確な型処理を行うには、数値カラムを適切な型にキャストするビューに対してクエリーを実行します。 この手法を使用すると、キャスト、フィルタリングおよび順序付けが正しいことを確認しながら、データベースアプリケーションから単純なSELECT *
クエリーを発行できます。 次の例は、母集団の降順で上位 3 か国を検索するためにクエリーすることができるビューを示しています。結果には、multicol
テーブルの最新データが反映され、母集団と面積の数値が数値として扱われます:mysql> CREATE VIEW populous_countries AS SELECT country, cast(population as unsigned integer) population, cast(area_sq_km as unsigned integer) area_sq_km, drive_side FROM multicol ORDER BY CAST(population as unsigned integer) DESC LIMIT 3; mysql> SELECT * FROM populous_countries; +---------+------------+------------+------------+ | country | population | area_sq_km | drive_side | +---------+------------+------------+------------+ | China | 1347350000 | 9640821 | R | | India | 1210193422 | 3287263 | L | | USA | 314242000 | 9826675 | R | +---------+------------+------------+------------+ mysql> DESC populous_countries; +------------+---------------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------+---------------------+------+-----+---------+-------+ | country | varchar(128) | NO | | | | | population | bigint(10) unsigned | YES | | NULL | | | area_sq_km | int(9) unsigned | YES | | NULL | | | drive_side | varchar(1) | YES | | NULL | | +------------+---------------------+------+-----+---------+-------+