↑上の青い「プログラム済み」をクリックしてフォローしてください~
これは Yasin の 83 番目のオリジナル記事です
最近、ビジネスではマルチバージョンのシナリオが多く使用されています。マルチバージョンのビジネスモデル設計の考え方をまとめました。
マルチバージョン要件の組み合わせ
まず、複数のバージョンの一般的な要件を整理します。
同じデータが複数回編集されると、複数のバージョンが生成されますが、上流と下流で使用される可能性があるため、履歴バージョンは削除できません。
通常、構成には複数のバージョンが使用され、最新バージョンの構成は通常、複数回変更およびテストされ、確認後にリリースされます。
公開されている過去のバージョンは、使用中のデータがあるため、気軽に変更することはできません。
コンシューマ側では、通常、最新リリースのバージョンがデフォルトで使用されます。
複数のバージョンには、リリースの承認や以前のバージョンとの差分などの要件シナリオが存在する場合があります。
マルチバージョンのステートマシン設計
マルチバージョンのビジネス モデルには通常、次のステート マシンがあります。このうち、「放棄」は必要なく、ロールバック操作も必要ありません(ロールバック操作はコードとテーブルの設計に大きな複雑さをもたらします)、リリース中に公開状態と承認状態が存在する可能性があります。
元のバージョンで下書きを編集することは可能ですが、公開されたデータを再度編集すると、新しいバージョンの下書きが生成されます。
場合によってはオフライン操作が発生し、その時点ですべてのバージョンのステータスが「オフライン」に変更されます。
マルチバージョンテーブル設計
id
複数のバージョンの場合は、ビジネス データを一意に識別するフィールド (またはと呼ばれる) が必要ですcode
。
同時に、バージョンを識別するためのフィールドが必要です。このバージョンは、 と呼ばれる増分番号であることが推奨されますversion
。企業によっては、バージョンが企業によって入力されることを期待している場合や、バージョンの説明の概念があるため、新しいフィールドを追加できる場合がありますversion_desc
。
一意の識別子とバージョンを、このバージョンのデータの一意のキーとして連結できます。これを と呼びますcode_version
。通常、これは文字列に連結され、中央で特定の区切り文字で区切られます (例: ) #
。それはcode_version
次のようになりますA12334#3
。code
ここでは、の中に区切り文字を含めないことが必要です#
。そうしないと、コード ロジックの処理が面倒になります。
コードとバージョンは上流と下流に保存されることが多いため、ここでこのスプライシング フィールドの必要性について説明します。リスト クエリなどのシナリオで上流と下流でデータをクエリする場合、そのようなフィールドがないと、where
ループ内で 1 つずつ検索することしかできず、バッチ クエリは使用できません。
もう 1 つの必須フィールドは、status
現在のバージョンのステータスを識別することです。
必須ではないフィールドもありますis_last_version
。これは、現在のデータが最新バージョンであるかどうか、ドラフト、公開済み、廃止されたものであるかどうかを識別するために使用され、それが true になります。その有用性については、以下のクエリ ポイントで説明します。このフィールドが必要ない場合はチェックできますが、必要な場合はgroup by order
、クエリ ステートメント全体が煩雑で非効率的になります。書き込み時にこのデータをより多く維持すると、クエリがさらに便利になります。
残りは監査フィールドです。最終的なテーブル作成ステートメントは次のようになります。
CREATE TABLE `t_xxx`
(
`id` bigint unsigned NOT NULL AUTO_INCREMENT COMMENT 'ID',
`code` varchar(255) NOT NULL DEFAULT '' COMMENT 'code',
`version` int NOT NULL DEFAULT 0 COMMENT '版本',
`version_desc` varchar(255) NOT NULL DEFAULT '' COMMENT '版本说明',
`code_version` varchar(255) NOT NULL DEFAULT '' COMMENT 'code和版本',
`is_last_version` tinyint NOT NULL DEFAULT '0',
`status` varchar(255) NOT NULL DEFAULT '' COMMENT '状态',
# 以下是业务字段...
`name` varchar(255) NOT NULL DEFAULT '' COMMENT '名称',
# 以下是审计字段...
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` varchar(10) NOT NULL DEFAULT '' COMMENT '创建人',
`modify_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
`modify_by` varchar(10) NOT NULL DEFAULT '' COMMENT '修改人',
`deleted_at` bigint DEFAULT '0' COMMENT '删除时间秒时间戳',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_code_version_deleted_at` (`code`, `version`, `deleted_at`)
) ENGINE = InnoDB
AUTO_INCREMENT = 5
DEFAULT CHARSET = utf8mb4
COLLATE = utf8mb4_0900_ai_ci COMMENT ='xxx表'
生産側と消費者側のクエリポイント
生産側はデータが構成される場所であり、消費者側はデータが使用される場所です。制作側と消費者側にはいくつかの違いがあり、多くの場合、制作側ではドラフトやその他の状態を含む最新バージョンを確認する必要があり、変更することができます。コンシューマ側は通常、最新リリースのバージョンのみを使用します。
制作側
本番側のクエリはis_last_version
true に応じてフィルタリングできるため、各コードの最新バージョンのみをチェックできます。
同時に、各コードは、ユーザーが履歴バージョンを表示してジャンプできるように、このデータのコレクションでversion
あるリストも返す必要があります。code_version
本番側で書き込むには、ステータス、バージョン、is_last_version
その他のフィールドを維持する必要があります。編集する際には現状がドラフトか公開かを判断する必要があり、公開されている場合は新たにレコードを作成する必要がある(もちろんフロントエンドでも判断できるが、バックエンドで検証する必要がある)更新しないなどのページ シナリオがデータの汚れを引き起こすことを防ぎます)。
消費者
コンシューマ側のクエリは、最新のリリース バージョンをクエリする必要があり、通常はステータスによってフィルタリングされますstatus = Online
。
しかし、ステータスに基づくフィルタリングには問題があります。過去にリリースされたバージョンはどうなるでしょうか? コードが 3 つのバージョンで公開されている場合、3 つのデータを見つけることは可能ではないでしょうか。この問題を解決するには 2 つの方法があります。
ステート マシンは、書き込み時に維持される Online_history 状態を追加します。
is_last_online_version をテーブルに追加し、書き込み時にこのフィールドを維持します。
個人的には、1 つのフィールドのメンテナンスが少なく、追加の列挙が 1 つだけ必要な最初のソリューションを使用することを好みます。
その他の注意事項
上流と下流
上流と下流の間のインターフェイスの対話では、code
最新のリリースされたバージョンを確認するという消費者側のシナリオを除いて、通常、対話にこれをcode_version
使用します。こうすることで、DB内のデータを直接ヒットすることができ、クエリするのに便利です。
code_version
異なるバージョンに関連付けられたデータは異なる可能性があるため、通常、このデータと他のデータの間の関係も保存に使用されます。
差分
Diff は、ドメイン モデルを json 化してから diff するためによく使用されます。ここの差分機能は、古い JSON と新しい JSON を渡して、どれが新しいか、どれが削除されるか、どれが変更されるかを返す一般的なサービスにすることができます。内部ロジックは通常、json_path と再帰メソッドを使用して実行されます。
diff の難しさは、それを構成可能にすること、どの属性が diff に参加するか、どの属性が diff を無視するかを構成することです。diffが出た後、キーをラベルに変換する必要があることが列挙され、外部変換関数があるか、フロントエンドがそれを転送できます。
もう 1 つ注意すべき点は、配列の順序です。一部のフィールドは json の配列ですが、ビジネス自体の順序は無関係であり、この種のデータの比較はさらに面倒になります。
ロールバック
公開バージョンの前のバージョンにロールバックしたり、リリース中にドラフト状態にロールバックしたりするなど、ロールバックは実際には非常に面倒です。主な理由は、前者は非常に面倒であり、特にアップストリームとダウンストリームがこのバージョンのデータを使用している場合、一般的に簡単にロールバックすることは許可されていないためです。
このようなシナリオがある場合、おそらくサービスリリースやアプリケーションリリースなどの上流と下流は存在しません。この種のロールバックの場合、通常、データの現在のバージョンは削除されませんが、特別な状態に設定されます。次回以前のバージョンを編集すると、生成されるバージョンは+1ではなく+2、場合によっては+nになってしまい、再度ライブラリを確認する必要があり面倒です。
したがって、特別なニーズがない場合は、リリースされたロールバックを実行する必要はありません。非常に複雑になります。
著者について
私はヤシン、ブログが大好きな技術者です。
WeChat パブリック アカウント: プログラムをコンパイルしました (blgcheng)
個人ウェブサイト:https://yasinshaw.com
この公開番号にご注目ください