MariaDB・TiDB で動かす(互換性と対応案)
本体の標準機能ではありません
Rds.json の Dbms に書ける値は SQLServer・PostgreSQL・MySQL の 3 つだけで、MariaDB と TiDB は対応 DBMS に入っていません。このページは、MySQL 用の実装をそのまま使った場合に何が起きるかと、対応を足す場合の改修箇所をまとめた設計メモです。
前提にした現行実装
RdsFactory.Create()はDbmsがSQLServer・PostgreSQL・MySQL以外ならNotSupportedExceptionを投げます(RdsFactory.cs)。- MySQL の接続には NuGet の
MySqlConnectorを使います。1.5.8.1 では 2.6.1 です(Implem.MySql.csproj)。 - MySQL ではすべてのコマンドの前に
set session sql_mode = 'ansi_quotes,pipes_as_concat';を送ります(MySqlCommandText.cs#L11-L14)。識別子を"で囲み、文字列の結合に||を使う SQL がこの設定を前提にしています。 - 全文索引は
create fulltext index "ftx" on "Items"("FullText") with parser "ngram";で作ります(CreateFullText.sql(MySQL))。CodeDefiner は全文索引の作成で例外が出てもコンソールに書いて続行します(TablesConfigurator.cs#L58-L78)。 Rds.jsonのProviderはAzureとそれ以外(Local扱い)の 2 通りで(Initializer.cs#L1026-L1034)、Localのときだけ CodeDefiner が DB・ユーザー・スキーマの作成と権限の付与を行います(Configurator.cs)。詳しくは Pleasanter Setup を参照してください。
MariaDB
互換性
| 区分 | 判定 | 内容 |
|---|---|---|
| 接続ライブラリ | 使える | MySqlConnector は MariaDB 10.x 以降に対応している(ライブラリの README による) |
| DDL・DML | 使える | create database ... collate utf8mb4_general_ci、create table、alter table modify column、インデックス・主キーの作成、insert ... select ... where not exists など |
with recursive | 10.2.2 以降 | GetGroupChildrenIds.sql、GetGroupParentIds.sql、MoveTarget.sql、RefreshAllChildMembers.sql で使う |
alter user ... identified by | 10.2 以降 | AlterLoginRole.sql で使う |
| ストアドプロシージャ | 使える | LdapUpdateGroupMembersAndChildren.sql など |
sql_mode の ANSI_QUOTES・PIPES_AS_CONCAT | 使える | |
全文索引の with parser "ngram" | 使えない | MariaDB には ngram パーサーが無い |
MariaDB で Dbms: "MySQL" のまま CodeDefiner を実行すると、テーブルは作られますが全文索引の作成が失敗します。失敗はコンソールに出るだけで CodeDefiner は続行するので、索引が無いまま運用が始まります。索引が無いと、全文検索(match ... against)を使う検索は機能しません。検索の仕組みは 検索機能の内部実装 にあります。
対応案
| 案 | 内容 | 日本語の検索 |
|---|---|---|
1. with parser "ngram" を外す | CreateFullText.sql を create fulltext index "ftx" on "Items"("FullText"); にする | 単語を空白で区切らない日本語は検索できない |
| 2. Mroonga を使う | MariaDB に Mroonga ストレージエンジンを入れ、Items テーブルを Mroonga で作り直す | 形態素解析か N-gram を選べる |
3. Dbms に MariaDB を足す | RdsFactory と各所の DBMS 分岐に MariaDB を足し、App_Data/Definitions/Sqls/MariaDB/ に専用の SQL を置く | 案 1 か案 2 を MariaDB 専用の SQL として持てる |
SQL ファイルの置き場所は Dbms の値ごとに分かれているので、MariaDB 専用の CreateFullText.sql を持つには案 3 が必要です。日本語の検索を使うなら、案 2 か、案 2 を含む案 3 になります。
TiDB
TiDB は MySQL のワイヤプロトコルと互換の分散 SQL データベースで、MySqlConnector で接続できます。
MySQL との違いで影響するもの
| 項目 | TiDB | Pleasanter への影響 |
|---|---|---|
| 全文索引 | v7.6 未満は非対応。v7.6 以降は tidb_ngram パーサー | with parser "ngram" の SQL は使えない |
PIPES_AS_CONCAT | v7.1 以降で対応 | 未対応の版では、文字列の結合演算子を使う LIKE 条件(MySqlSqls の WhereLikeTemplate など)が正しく動かない |
ANSI_QUOTES | v5.0 以降で対応 | |
with recursive | v5.0 以降で対応 | |
AUTO_INCREMENT | ノードごとにまとめて割り当てる(既定 30000 単位)ので連番にならない | last_insert_id() は正しい値を返すので採番の取得(SelectIdentity.sql)は動く |
information_schema.tables.AUTO_INCREMENT | 割り当て済みの次の開始値 | CodeDefiner の IDENTITY 列の判定は NOT NULL かどうかだけを見るので影響しない |
| DDL | オンライン DDL(非同期) | 大きなテーブルの移行に時間がかかることがある |
| 既定のポート | 4000 | 接続文字列で指定する |
TiDB の仕様は調査時点の TiDB のドキュメントによります。
改修案(Dbms: "TiDB" を足す)
MySQL の別名として扱う方法もありますが、全文索引の違いを分けて持てるよう、新しい Dbms の値を足す方が既存の SQL Server・PostgreSQL・MySQL と同じ構造になります。接続まわりのクラスは MySQL のものを流用できます。
1.5.8.1 で "MySQL" を条件にしている主な箇所は次のとおりで、ここに "TiDB" を足します。
| 箇所 | 内容 |
|---|---|
Implem.Factory/RdsFactory.cs | TiDB なら MySQL の実装をもとにしたファクトリを返す |
Implem.CodeDefiner/Starter.cs | DBMS の妥当性チェック |
Implem.CodeDefiner/Functions/Rds/Configurator.cs | 接続文字列から Server・Database を取り出す(MySqlConnectionStringBuilder) |
UsersConfigurator.cs / PrivilegeConfigurator.cs | MySqlConnectingHost のホストごとにユーザー・権限を作る |
Parts/Columns.cs / Parts/Constraints.cs / Parts/Indexes.cs | スキーマの比較と移行 |
TablesConfigurator.cs | 全文索引の作成。TiDB 用の分岐を作り、版によって作らないか tidb_ngram で作る |
Libraries/Extensions/HealthCheckExtensions.cs | ヘルスチェック(AddMySql を流用) |
Libraries/BackgroundServices/CustomQuartzHostedService.cs | Quartz.NET のプロバイダー名と MySQLDelegate |
Libraries/Server/DistributedLock.cs | 分散ロック(MySQL では get_lock / release_lock) |
Libraries/DataTypes/Attachment.cs | バイナリのハッシュ |
Implem.Libraries/DataSources/SqlServer/SqlDebugs.cs / SqlSelect.cs | ログのオプション、MySQL 固有のクエリ変換 |
あわせて、App_Data/Definitions/Sqls/TiDB/ に MySQL の SQL を複製し、CreateFullText.sql だけを差し替えます。
create fulltext index "ftx" on "Items"("FullText") with parser "tidb_ngram";v7.6 未満も対象にするなら、Rds.json に全文索引を作るかどうかのフラグ(例: TiDBFullTextEnabled)を足し、false のときは作成を飛ばします。この場合、全文検索は使えません。DistributedLock.cs の get_lock / release_lock が TiDB で使えるかは、このページでは確認していません。
図を読み込み中…
マネージドサービス
TiDB Cloud のように DB やユーザーを CodeDefiner から作れない環境では、Provider を Azure にすると DB・ユーザーの作成と権限の付与が飛ばされ、あらかじめ用意した DB にテーブルだけを作れます。Aurora MySQL も Dbms: "MySQL" で同じように扱えます。
| 対象 | 推奨する版 |
|---|---|
| 全文検索を使う | v7.6 以降 |
| 最低限 | v7.1 以降(PIPES_AS_CONCAT のため) |