sql >> データベース >  >> RDS >> Mysql

2018年のMySQL:8.0およびその他の所見の内容

    2018年のすべてではないにしても、ほとんどの場合(この投稿を読んでいる時期によって異なります)、オープンソースのSQLデータベースにとって素晴らしい年であったことは間違いありません。

    PostgreSQL11とMySQL8の両方がリリースされ、両方のコミュニティに'話し合うたくさんの情報を提供しました。 '。正直なところ、どちらのベンダーもそれぞれのリリースに多くの重要な変更と追加を導入しており、賞賛と称賛に値します。

    私は通常、前者についていくつかのブログにゲスト投稿します(素晴らしい組織に感謝します!)が、後者にも興味があります。私自身のウェブサイト(私の略歴セクションのリンク)に多くのブログ投稿があり、主にMySQLバージョン5.7を対象としているため、それ(MySQL)は常に私の周辺機器にあります。

    では、MySQL 8にはバージョン5.7にはないものがありますか?改善点は何ですか?まあ、たくさんあります。実際、1つのブログ投稿でカバーするには多すぎます。

    最近、現在のLinux学習/開発環境でバージョン8にアップグレードしたので、それらのいくつかを指摘してみようと思いました。

    'お気に入りについての詳細な議論を保証することはできません '新機能。一方で、個人的な興味や、バージョン8で年間を通じて公開されている多くの素晴らしいブログ投稿を通じて私の注目を集めている人々を訪問します。

    MySQLはどんどん良くなっています...バージョン8での大幅な改善!

    ロール

    ロールを使用すると、DBAは冗長性を軽減でき、多くのユーザーが同じ特権または特権のセットを共有します。

    役割はSQL標準の一部です。

    必要な/必要な特権を持つ特定の役割を作成した後、GRANTコマンドを使用して、または同様に、ユーザーにその特定の役割を割り当てることができます。'削除 'REVOKEを使用します。

    役割には多くの利点があり、生活を少し楽にするために、役割を追跡するのに役立つ表がいくつかあります。

    • mysql.role_edges-ここに、それらのロールとそれらが割り当てられているユーザーがあります。

      mysql> DESC mysql.role_edges;
      +-------------------+---------------+------+-----+---------+-------+
      | Field             | Type          | Null | Key | Default | Extra |
      +-------------------+---------------+------+-----+---------+-------+
      | FROM_HOST         | char(60)      | NO   | PRI |         |       |
      | FROM_USER         | char(32)      | NO   | PRI |         |       |
      | TO_HOST           | char(60)      | NO   | PRI |         |       |
      | TO_USER           | char(32)      | NO   | PRI |         |       |
      | WITH_ADMIN_OPTION | enum('N','Y') | NO   |     | N       |       |
      +-------------------+---------------+------+-----+---------+-------+
      5 rows in set (0.01 sec)
    • mysql.default_roles-デフォルトのロールと割り当てられたユーザーを保存します。

      mysql> DESC mysql.default_roles;
      +-------------------+----------+------+-----+---------+-------+
      | Field             | Type     | Null | Key | Default | Extra |
      +-------------------+----------+------+-----+---------+-------+
      | HOST              | char(60) | NO   | PRI |         |       |
      | USER              | char(32) | NO   | PRI |         |       |
      | DEFAULT_ROLE_HOST | char(60) | NO   | PRI | %       |       |
      | DEFAULT_ROLE_USER | char(32) | NO   | PRI |         |       |
      +-------------------+----------+------+-----+---------+-------+
      4 rows in set (0.00 sec)

    両方のテーブルの組み合わせ(SQL JOINの意味ではありません)は、基本的に「集中化された場所」を提供します。 'ここでできること:実装されたすべてのユーザーと役割の特権の関係と割り当てを知り、監視し、評価します。

    おそらく最も単純なロール使用シナリオの例は次のとおりです。

    '読み取り専用アクセスを必要とするユーザーが何人かいます '特定のテーブルでは、したがって、少なくともSELECT特権が必要です。各ユーザーに個別に付与(SELECT)する代わりに、その特権を持つロールを確立(作成)してから、そのロールをそれらのユーザーに割り当てることができます。

    ただし、役割には小さな「キャッチ」が付属しています。 '。作成してユーザーに割り当てたら、ログイン時の認証時に、受信ユーザーにアクティブなデフォルトの役割を設定する必要があります。

    ロールとユーザーについては、バージョン5.7で使用されているvalidate_passwordプラグインのバリアントであるvalidate_passwordコンポーネントに関してMySQL8で実装された変更について言及することが重要だと思います。

    このコンポーネントは、さまざまな異なる'カテゴリを提供します 'パスワードチェックの'低、中(デフォルト)、および強力。各レベルの検証の詳細の詳細については、validate_passwordコンポーネントのドキュメントをご覧ください。

    NoSQLとSQLの混合-ドキュメントストア

    この機能は、2016年の初めにMongoDBに一瞬の関心があったにもかかわらず、私がまだ学んでいる機能です。これまで、私の関心、研究、学習は「SQL」のみに焦点を当ててきました。ただし、MySQL 8ドキュメントストアで現在利用可能な「リレーショナルSQL」と絡み合ったこのタイプの構造化(ドキュメント指向)に多くの人が興奮していることを(Webでよく読んで)知っています。

    以下は、ドキュメントストアを使用するときに利用できる多くの利点です。コメントセクションで見逃したかもしれないお気に入りを必ず挙げてください:

    • JSONデータ型はMySQLバージョン5.7.8からサポートされていますが、バージョン8ではJSONを操作するための大幅な機能拡張が導入されています。 '省略形とともに新しいJSON固有の関数 '複数の関数呼び出しの代わりに使用できる演算子-同等の結果/出力。
    • ドキュメントストアではNoSQL、SQL、またはその2つの組み合わせがサポートされているため、おそらく最大のメリットの1つは、複数のデータベースソリューションを実装して操作する必要がなくなることです。
    • 「DevAPI」は、NoSQLデータコンテキスト(コレクションとドキュメント)内でシームレスなワークフロー機能を提供します。 (詳細については、公式のDevAPIユーザーガイドドキュメントをご覧ください)。
    • 「シェル」言語としてPython、SQL、またはJavascriptを使用する強力なコマンドラインセッション。
    • ACID準拠。
    • リレーショナルモデルのようにスキーマを定義しなくても、データをすばやく探索して発見できます。

    一般的なテーブル式(CTEまたはWITH句)

    CTEについて他に何が言えますか?これらはゲームチェンジャーです!手始めに、一般的なテーブル式とは正確には何ですか?

    ウィキペディアから:

    「(SQLの)共通テーブル式(CTE)は、単純なクエリから派生し、SELECT、INSERT、UPDATE、またはDELETEステートメントの実行スコープ内で定義された一時的な名前付き結果セットです。」

    CTEを示す簡単な例を示します。ただし、これらよりも複雑なユースケースの例が多数あるため、このセクションではそれらのフルパワーを活用していません。

    この説明とデータを含む簡単な名前の表があります:

    mysql> DESC name;
    +--------+-------------+------+-----+---------+-------+
    | Field  | Type        | Null | Key | Default | Extra |
    +--------+-------------+------+-----+---------+-------+
    | f_name | varchar(20) | YES  |     | NULL    |       |
    | l_name | varchar(20) | YES  |     | NULL    |       |
    +--------+-------------+------+-----+---------+-------+
    2 rows in set (0.00 sec)
    mysql> SELECT * FROM name;
    +--------+------------+
    | f_name | l_name     |
    +--------+------------+
    | Jim    | Dandy      |
    | Johhny | Applesauce |
    | Ashley | Zerro      |
    | Ashton | Zerra      |
    | Ashmon | Zerro      |
    +--------+------------+
    5 rows in set (0.00 sec)

    「Z」で始まる名前の数を調べましょう:

    mysql> SELECT *
        -> FROM name
        -> WHERE l_name LIKE 'Z%';
    +--------+--------+
    | f_name | l_name |
    +--------+--------+
    | Ashley | Zerro  |
    | Ashton | Zerra  |
    | Ashmon | Zerro  |
    +--------+--------+
    3 rows in set (0.00 sec)

    簡単です。

    ただし、WITH句を使用すると、'アクセスできます。 'これと同じクエリ結果セット(派生テーブルと考えることができます)を作成し、後で同じステートメント内で参照します-または' scope ':

     WITH last_Z AS (
               SELECT *
               FROM name
               WHERE l_name LIKE 'Z%')
       SELECT * FROM last_Z;
    +--------+--------+
    | f_name | l_name |
    +--------+--------+
    | Ashley | Zerro  |
    | Ashton | Zerra  |
    | Ashmon | Zerro  |
    +--------+--------+
    3 rows in set (0.00 sec)

    基本的に、クエリに名前を割り当て、括弧で囲みます。次に、現在のlast_ZCTEから必要なデータを選択するだけです。

    last_Z CTEは完全な結果セットを提供するため、同じステートメント内でさらにフィルタリングできます。

    WITH last_Z AS ( 
               SELECT *
               FROM name
               WHERE l_name LIKE 'Z%')
       SELECT f_name, l_name FROM last_Z WHERE l_name LIKE '%a';
    +--------+--------+
    | f_name | l_name |
    +--------+--------+
    | Ashton | Zerra  |
    +--------+--------+
    1 row in set (0.00 sec)

    より強力な機能のいくつかは、'チェーンです。 '複数のCTEが一緒になっており、CTE内の他のCTEを参照しています。

    これがあなたにアイデアを与えるための例です(それほど有用ではありませんが):

    WITH last_Z AS ( 
               SELECT *
               FROM name
               WHERE l_name LIKE 'Z%'),
            best_friend AS (
               SELECT f_name, l_name
               FROM last_Z
               WHERE l_name LIKE '%a')
       SELECT * from best_friend;
    +--------+--------+
    | f_name | l_name |
    +--------+--------+
    | Ashton | Zerra  |
    +--------+--------+
    1 row in set (0.00 sec)

    上記のクエリでは、last_ZCTEとbest_friendCTEをコンマで区切り、そのクエリをASキーワードの後に​​括弧で囲んでいることがわかります。

    その後、last_Z CTEを参照(および使用)して、基本的にbest_friendCTEを定義できることに注意してください。

    CTEがバージョン8でこれほど大幅に改善された理由は、次のとおりです。

    • 他のSQLベンダーはCTEをサポートしており(多くは個々のエコシステム内の以前のバージョンから)、現在はMySQL8がこの領域のギャップを埋めています。
    • 標準のSQLインクルージョン。
    • 場合によっては(適切な場合)、一時テーブル、ビュー、派生テーブル(またはインラインビュー)、および一部のサブクエリよりもCTEの方が適しています。
    • CTEは'オンザフライを提供できます 'クエリできる計算結果セット。
    • CTEはそれ自体を参照できます-再帰CTEとして知られています(ここでは示されていません)。
    • CTEは、他のCTEに名前を付けて使用できます
    データベースインフラストラクチャ全体のClusterControlSingleコンソールClusterControlのその他の新機能を確認するClusterControlを無料でインストール

    ウィンドウ関数

    MySQL 8で分析クエリが可能になりました。ウィンドウ関数は私の強みではないため、全体として、より詳細な調査とそれらの理解を深めることに重点を置いています。これらの次の例は、私の理解によれば、ほとんどが初歩的なものです。読者からの提案、アドバイス、ベストプラクティスを歓迎します。

    架空のパイプデータ結果セット(私がある程度理解しているもの)を提供するこのビューがあります:

    mysql> SELECT * FROM pipe_vw;
    +---------+-------------+-----------+-------+-------------+------------+----------------+
    | pipe_id | pipe_name   | joint_num | heat  | pipe_length | has_degree | wall_thickness |
    +---------+-------------+-----------+-------+-------------+------------+----------------+
    |     181 | Joint-278   | 39393A    | 9111  |       17.40 |          1 |          0.393 |
    |     182 | Joint-8819  | 19393Y    | 9011  |       16.60 |          0 |          0.427 |
    |     183 | Joint-9844  | 39393V    | 8171  |       10.40 |          0 |          0.393 |
    |     184 | Joint-2528  | 34493U    | 9100  |       11.50 |          1 |          0.427 |
    |     185 | Joint-889   | 18393z    | 9159  |       13.00 |          0 |          0.893 |
    |     186 | Joint-98434 | 19293Q    | 8174  |        9.13 |          0 |          0.893 |
    |     187 | Joint-78344 | 17QTT     | 179   |       44.40 |          1 |          0.893 |
    |     188 | Joint-171C  | 34493U    | 17122 |        9.45 |          1 |          0.893 |
    |     189 | Joint-68444 | 17297Q    | 6114  |       11.34 |          0 |          0.893 |
    |     190 | Joint-4841R | 19395Q    | 5144  |       25.55 |          0 |          0.115 |
    |     191 | Joint-1224C | 34493U    | 8575B |       15.22 |          1 |          0.893 |
    |     192 | Joint-2138  | 34493C    | 91    |       13.55 |          1 |          0.893 |
    |     193 | Joint-122B  | 34493U    | 9100B |        7.78 |          1 |          0.893 |
    +---------+-------------+-----------+-------+-------------+------------+----------------+
    13 rows in set (0.00 sec)

    想像してみてください。個々のパイプの長さに応じて、ある種の行ランキングでパイプ資産レコードを表示する必要があります。 (たとえば、最長の長さは「ラベル付け」された番号1の位置、2番目に長い長さは「ラベル付けされた」位置2など)

    ドキュメントのRANK()ウィンドウ関数の説明に基づく:

    "パーティション内の現在の行のランクをギャップ付きで返します。ピアは同点と見なされ、同じランクを受け取ります。この関数は、サイズが1より大きいグループが存在する場合、ピアグループに連続したランクを割り当てません。結果は非連続のランク番号になります。 。"

    この要件に適しているようです。

    mysql> SELECT pipe_name, pipe_length,
        -> RANK() OVER(ORDER BY pipe_length DESC) AS long_to_short
        -> FROM pipe_vw;
    +-------------+-------------+---------------+
    | pipe_name   | pipe_length | long_to_short |
    +-------------+-------------+---------------+
    | Joint-78344 |       44.40 |             1 |
    | Joint-4841R |       25.55 |             2 |
    | Joint-278   |       17.40 |             3 |
    | Joint-8819  |       16.60 |             4 |
    | Joint-1224C |       15.22 |             5 |
    | Joint-2138  |       13.55 |             6 |
    | Joint-889   |       13.00 |             7 |
    | Joint-2528  |       11.50 |             8 |
    | Joint-68444 |       11.34 |             9 |
    | Joint-9844  |       10.40 |            10 |
    | Joint-171C  |        9.45 |            11 |
    | Joint-98434 |        9.13 |            12 |
    | Joint-122B  |        7.78 |            13 |
    +-------------+-------------+---------------+
    13 rows in set (0.01 sec)

    次のシナリオでは、前の例をさらに発展させて、最長から最短の長さのレコードをランク​​付けしますが、個別のwall_thickness値の個々のグループごとにランク付けします。

    おそらく、以下のクエリと結果は、私の散文がそうではなかったかもしれないところをよりよく説明するでしょう:

    mysql> SELECT pipe_name, pipe_length, wall_thickness,
        -> RANK() OVER(PARTITION BY wall_thickness ORDER BY pipe_length DESC) AS long_to_short
        -> FROM pipe_vw;
    +-------------+-------------+----------------+---------------+
    | pipe_name   | pipe_length | wall_thickness | long_to_short |
    +-------------+-------------+----------------+---------------+
    | Joint-4841R |       25.55 |          0.115 |             1 |
    | Joint-278   |       17.40 |          0.393 |             1 |
    | Joint-9844  |       10.40 |          0.393 |             2 |
    | Joint-8819  |       16.60 |          0.427 |             1 |
    | Joint-2528  |       11.50 |          0.427 |             2 |
    | Joint-78344 |       44.40 |          0.893 |             1 |
    | Joint-1224C |       15.22 |          0.893 |             2 |
    | Joint-2138  |       13.55 |          0.893 |             3 |
    | Joint-889   |       13.00 |          0.893 |             4 |
    | Joint-68444 |       11.34 |          0.893 |             5 |
    | Joint-171C  |        9.45 |          0.893 |             6 |
    | Joint-98434 |        9.13 |          0.893 |             7 |
    | Joint-122B  |        7.78 |          0.893 |             8 |
    +-------------+-------------+----------------+---------------+
    13 rows in set (0.00 sec)

    このクエリでは、wall_thickness列のPARTITION BY句を使用します。これは、ランキング(ORDER BY pipe_length DESCが提供するもの)が必要なためですが、個々のwall_thicknessグループのコンテキストで必要です。

    異なるwall_thickness列の値に遭遇(または変更)すると、各long_to_short列のランキングは1にリセットされます。

    1つのグループの結果に集中しましょう。

    wall_thickness値が0.893のレコードをターゲットにすると、pipe_length 44.40の行の対応するlong_to_short'ランキング'は1(最長)になり、pipe_length 7.78の行の対応するlong_to_short'ランキング'は8(最短)になります。 wall_thickness値の特定のグループ(0.893)。

    ウィンドウ関数は非常に強力であり、その範囲と幅全体を1つのセクションだけでカバーすることはできません。現在利用可能なウィンドウ関数の詳細については、MySQL8のドキュメントでサポートされているウィンドウ関数を確認してください。

    改善された空間サポートと機能

    これは、MySQL 8に含まれている膨大な機能のセットです。以前のバージョンのサポートまたはその欠如は、他のベンダーの実装と比較することはできませんでした(PostgreSQL用のPostGISを考えてください)。

    過去10年以上、私はこの分野でパイプライン測量士としてGPSと資産データを収集してきました。そのため、この一連の変更は間違いなく私の注目を集めています。

    空間データの専門知識はそれ自体が包括的な主題であり、確かに、私はそれに関する専門家からはほど遠いです。ただし、バージョン5.7とバージョン8の間の重要な変更点を要約し、明確かつ簡潔に伝えたいと思います。

    このセクションでは、2つの重要な用語(および概念)を理解しましょう。

    1. 空間参照系またはSRS-ウィキペディアからの部分的な定義は次のとおりです:

      「空間参照系(SRS)または座標参照系(CRS)は、地理的エンティティの位置を特定するために使用される座標ベースのローカル、地域、またはグローバルシステムです。空間参照系は、特定のマップ投影、および異なる空間参照間の変換を定義します。システム。」

    2. 空間参照系識別子またはSRID-また、ウィキペディアにはSRIDが次のように定義されています:

      「空間参照系識別子(SRID)は、投影、非投影、およびローカルの空間座標系の定義を明確に識別するために使用される一意の値です。これらの座標系は、すべてのGISアプリケーションの中心を形成します。」

    MySQLは多くの空間データ型をサポートしています。最も一般的なものの1つはPOINTです。 GPSを使用してお気に入りのレストランに移動する場合、その場所は地図上のポイントです。

    MySQL 5.7は、ほぼすべての'空間オブジェクトを処理します 'SRIDが0であるため、これは計算にとって重要です。これらの計算は、デカルトタイプの座標系で計算されます。しかし、私たちの地球は球体であり、平らにはほど遠いことは誰もが知っています。したがって、バージョン8では、計算でフラットまたは球形と見なすことができます。

    これらの2つの用語に戻り、以前に定義しました。

    MySQLバージョン8のデフォルトのSRIDは0ですが、他の多くの(約5,000以上の)SRIDがサポートされています。

    しかし、なぜそれが重要なのでしょうか?

    ブログ投稿「MySQL8.0の空間参照系」によるこの素晴らしい説明は、それをうまくまとめています:

    「デフォルトでは、SRIDを指定しない場合、MySQLはSRID 0でジオメトリを作成します。SRID0は、MySQLの抽象的な、単位のない、無限のCatesian平面の概念です。他のすべてのSRSは、いくつかのサーフェスを参照し、軸、SRID0はしません。」

    基本的に、SRIDの SRID0以外を使用して計算を実行する場合 、次に、私たちの地球の形が作用し、考慮され、それらの計算に影響を与えます。これは、意味のある/正確な計算にとって非常に重要です。詳細な概要とより適切な外挿については、MySQL8の地理をカバーするこのブログ投稿を参照してください。

    また、SRSを明確にするために、MySQLサーバーチームのブログ投稿であるMySQL8.0の地理空間参照系を強くお勧めします。必ず読んでください!

    最後に、バージョン5.7から8への空間データのアップグレードに関する懸念事項については、ここにリストされている互換性のない変更のいくつかにアクセスして、詳細を確認してください。

    その他の注目すべき所見

    以下は、私が認めなければならない他のリリースの機能強化ですが、このブログ投稿では詳しく説明されていません。

    • utf8mb4がデフォルトの文字セット(以前はlatin1)になりました-一部の言語に加えて絵文字が必要な場合のサポートが向上します...
    • トランザクションデータディクショナリ-MySQLメタデータがInnoDBテーブルに格納されるようになりました。
    • 非表示のインデックス-オプティマイザーのインデックスの可視性を設定し、最終的にそれ(インデックス)を追加または削除することが良いか悪いかを判断します。既存の大きなテーブルにインデックスを追加すると、'高価になる可能性があります 'ロックとリソースの観点から。
    • インデックスの降順-降順で保存されるインデックス値のパフォーマンスが向上します。
    • Instant Add Column-スキーマを変更する場合は、ALTERTABLEステートメントでALGORITHM=INSTANTを指定し、(操作が可能な場合は)メタデータロックを回避します。 (詳細については、MySQLサーバーチームによるこのすばらしい投稿、および公式ドキュメントのALTER TABLEセクションを参照してください。)

    ボーナスセクション:私が見たかったもの...

    関連リソースClusterControlforMySQLがMySQLDBAブログシリーズになる-一般的な操作-レプリケーショントポロジの変更がMySQLDBAブログシリーズになる-データベースのアップグレード

    チェック制約はまだMySQL製品に組み込まれていません。

    以前のMySQLバージョンと同様に、チェック制約構文はCREATE TABLEコマンドで許可されていますが、無視されます。私の知る限り、他のほとんどのSQLベンダーはチェック制約をサポートしています。 MySQLのパーティーに参加してください!

    MySQLは大幅に'ステップアップしました 'バージョン8での提供。堅牢な空間機能、便利なユーザー管理ロールオプション、'ハイブリッド'SQL / NoSQLデータソリューション、および多数の追加の改善の中で分析機能をサポートすることは、本当に注目に値します。

    私の意見では、バージョン8で、MySQLは、関連性があり機能が豊富なソリューションでいっぱいの、成長を続ける競争力のあるオープンソースSQLエコシステムで確固たるオプションを提供し続けます。

    読んでいただきありがとうございます。


    1. MariaDBでのINSERT()関数のしくみ

    2. 日付に追加または日付から減算するときのSQLServerの「日付がintと互換性がない」を修正

    3. psqlでデータベースを切り替える方法は?

    4. Linuxプラットフォーム用のOracleDatabase21c