Documentation Home
MySQL 8.0 リファレンスマニュアル
Download this Manual
PDF (US Ltr) - 36.1Mb
PDF (A4) - 36.2Mb


このページは機械翻訳したものです。

15.20.6.1 InnoDB memcached プラグイン用の既存の MySQL スキーマの適応

既存の 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 @@name の形式で memcached リクエストを発行して、後続の memcached リクエストに使用するテーブルを指定します。

    事前定義された 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 スクリプトを実行するようにシステムが構成されていることも前提としています。

  1. 母集団、地域およびドライバ側のデータを含む国情報を格納する 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;
  2. 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 つのテーブルのカラム (populationarea_sq_km および drive_side) に分割されます。 複数の値カラムに対応するには、value_columns フィールドにカンマ区切りのカラムリストを指定します。 value_columns フィールドに定義されているカラムは、値の格納または取得時に使用されるカラムです。

    • flagsexpire_time および cas_column の各フィールドの値は、demo.test サンプルテーブルで使用されている値に基づきます。 これらのフィールドは通常、daemon_memcached プラグインを使用するアプリケーションでは重要ではありません。これは、MySQL がデータの同期を維持し、データの期限切れや失効を心配する必要がないためです。

    • unique_idx_name_on_key フィールドが PRIMARY に設定され、multicol テーブルの一意の country カラムに定義されているプライマリインデックスを参照します。

  3. サンプル 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 テーブルのカラムにマップする場合にのみ必要です。

  4. サンプル 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
  5. 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
  6. 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 値は、意味のない数値を生成する可能性のある一部の文字を削除することによって切り捨てられます。

  7. オプションで、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    |       |
    +------------+---------------------+------+-----+---------+-------+