マルチバージョンのビジネスモデル設計

↑上の青い「プログラム済み」をクリックしてフォローしてください~

6a7049e43b188c221a7d1a86f5944d3d.png

これは Yasin の 83 番目のオリジナル記事です

8ffe61e98​​6df92d5d2c4e55788381799.png

最近、ビジネスではマルチバージョンのシナリオが多く使用されています。マルチバージョンのビジネスモデル設計の考え方をまとめました。

マルチバージョン要件の組み合わせ

まず、複数のバージョンの一般的な要件を整理します。

  1. 同じデータが複数回編集されると、複数のバージョンが生成されますが、上流と下流で使用される可能性があるため、履歴バージョンは削除できません。

  2. 通常、構成には複数のバージョンが使用され、最新バージョンの構成は通常、複数回変更およびテストされ、確認後にリリースされます。

  3. 公開されている過去のバージョンは、使用中のデータがあるため、気軽に変更することはできません。

  4. コンシューマ側では、通常、最新リリースのバージョンがデフォルトで使用されます。

  5. 複数のバージョンには、リリースの承認や以前のバージョンとの差分などの要件シナリオが存在する場合があります。

マルチバージョンのステートマシン設計

マルチバージョンのビジネス モデルには通常、次のステート マシンがあります。このうち、「放棄」は必要なく、ロールバック操作も必要ありません(ロールバック操作はコードとテーブルの設計に大きな複雑さをもたらします)、リリース中に公開状態と承認状態が存在する可能性があります。

元のバージョンで下書きを編集することは可能ですが、公開されたデータを再度編集すると、新しいバージョンの下書きが生成されます。

3a79dc3b8f0f2f52557c5c38b4d6e876.png

場合によってはオフライン操作が発生し、その時点ですべてのバージョンのステータスが「オフライン」に変更されます。

マルチバージョンテーブル設計

id複数のバージョンの場合は、ビジネス データを一意に識別するフィールド (またはと呼ばれる) が必要ですcode

同時に、バージョンを識別するためのフィールドが必要です。このバージョンは、 と呼ばれる増分番号であることが推奨されますversion企業によっては、バージョンが企業によって入力されることを期待している場合や、バージョンの説明の概念があるため、新しいフィールドを追加できる場合がありますversion_desc

一意の識別子とバージョンを、このバージョンのデータの一意のキーとして連結できます。これを と呼びますcode_version通常、これは文字列に連結され、中央で特定の区切り文字で区切られます (例: ) #それはcode_version次のようになりますA12334#3codeここでは、の中に区切り文字を含めないことが必要です#。そうしないと、コード ロジックの処理が面倒になります。

コードとバージョンは上流と下流に保存されることが多いため、ここでこのスプライシング フィールドの必要性について説明します。リスト クエリなどのシナリオで上流と下流でデータをクエリする場合、そのようなフィールドがないと、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_versiontrue に応じてフィルタリングできるため、各コードの最新バージョンのみをチェックできます。

同時に、各コードは、ユーザーが履歴バージョンを表示してジャンプできるように、このデータのコレクションで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になってしまい、再度ライブラリを確認する必要があり面倒です。

したがって、特別なニーズがない場合は、リリースされたロールバックを実行する必要はありません。非常に複雑になります。

7c4c1eb0f3750f66579b0a8b0e446b09.png

著者について

私はヤシン、ブログが大好きな技術者です。

WeChat パブリック アカウント: プログラムをコンパイルしました (blgcheng)

個人ウェブサイト:https://yasinshaw.com

この公開番号にご注目くださいeea9ecadd344266d666282f769e219c0.png

19eb3ee81d36840fea458ce87d4d5c55.png

おすすめ

転載: blog.csdn.net/yasinshaw/article/details/129272999