Click ↑ above ↑ blue " programmed " to follow me~
This is Yasin's 83rd original article
Recently, many multi-version scenarios have been used in business. Here is a summary of the idea of multi-version business model design.
Multi-version requirements combing
First sort out the general requirements of multiple versions:
After the same data has been edited multiple times, multiple versions will be generated, and the historical version cannot be deleted, because there may be upstream and downstream uses;
Multiple versions are usually used in configuration, and the configuration of the latest version can usually be modified and tested multiple times, and released after confirmation;
The published historical version cannot be modified casually, because there is data in use;
On the consumer side, the latest released version is generally used by default;
Multiple versions may have requirement scenarios such as release approval and diff with the previous version;
Multi-version state machine design
A multi-version business model usually has the following state machines. Among them, "abandoned" is not necessary, and the rollback operation is not necessary (rollback operation will bring great complexity to the code and table design), and there may be publishing and approval states during the release.
The draft can be edited in the original version, but if the published data is edited again, a new version of the draft will be generated.
Sometimes there will be an offline operation, and at this time the status of all versions will be changed to "offline".
Multi-version table design
For multiple versions, you need to have a field that uniquely identifies the business data, which can be called id
or code
.
At the same time, a field is required to identify the version. This version is suggested to be an incremental number called version
. Some businesses expect the version to be entered by the business, or have a concept of version description, so a new field can be added version_desc
.
We can concatenate the unique identifier and version as the unique key of this data in this version, which can be called code_version
. It is usually concatenated into a string, separated by a specific separator in the middle, for example #
. That code_version
might look like this: A12334#3
. Here it is required that code
there should be no separators inside #
, otherwise the code logic will be troublesome to process.
Let me talk about the necessity of this splicing field here, because code + version is often stored upstream and downstream. When upstream and downstream query data in scenarios such as list query, if there is no such field, they can only where
search one by one in a loop, and batch query cannot be used.
Another required field is status
to identify the status of the current version.
There is also a non-required field is_last_version
, which is used to identify whether the current piece of data is its latest version, whether it is a draft, published or obsolete, it will become true. Its usefulness is explained here in the query points below. If you don’t need this field, you can check it, but if you need it group by order
, the overall query statement is cumbersome and inefficient. Maintaining this data more when writing will make querying much more convenient.
The rest are audit fields. The final table creation statement may look like this:
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表'
Query points on the production end and consumer end
The production end is where data is configured, and the consumer end is where data is used. There are some differences between the production end and the consumer end. The production end often needs to see the latest version, including drafts and other states, and can be modified. The consumer side generally only uses the latest released version.
production end
The query on the production side can is_last_version
be filtered according to true, so that only the latest version of each code can be checked.
At the same time, each code should also return a version
list, which is code_version
a collection of this data, so that users can view and jump to historical versions.
When writing on the production side, you need to maintain the status, version, is_last_version
and other fields. When editing, it is necessary to judge whether the current status is a draft or published. If it is published, a new record needs to be created (of course, this can also be judged on the front end, but the back end must be verified to prevent page Scenarios such as not refreshing cause dirty data).
Consumer
The query on the consumer side needs to query the latest released version, which is usually filtered by status, for example status = Online
.
But here is a problem with filtering based on status: what about historically released versions? If a code is released in 3 versions, wouldn't it be possible to find out 3 pieces of data? There are two ways to solve this problem:
The state machine adds an Online_history state, which is maintained when writing;
Add an is_last_online_version to the table, and maintain this field when writing;
Personally, I prefer to use the first solution, which requires less maintenance of one field and only one more enumeration.
other precautions
upstream and downstream
In the interface interaction between upstream and downstream, we code
usually code_version
use . In this way, a piece of data can be directly hit in the DB, and it is convenient to query.
The relationship between this data and other data is also usually used code_version
to save, because the data associated with different versions may be different.
diff
Diff is often used to jsonize the domain model and then diff. The diff capability here can be made into a general service, passing in old json and new json, and returning which ones are new, which ones are deleted, and which ones are changed. Internal logic is generally done using json_path and recursive methods.
The difficulty of diff is to make it configurable, configure which attributes participate in diff, and which attributes ignore diff. After the diff comes out, it may be enumerated that the key needs to be converted into a label, and there is an external conversion function, or the front end can transfer it.
Another piece to watch out for is the order of the arrays. Although some fields are arrays in json, the order of the business itself is irrelevant, and the comparison of this kind of data will be more troublesome.
rollback
Rolling back is actually very troublesome, including rolling back to the previous version of the published version, and rolling back to the draft state during the release. The main reason is that the former is very troublesome, especially if the upstream and downstream use this version of data, it is generally not allowed to roll back easily.
If there is such a scenario, there is probably no upstream and downstream, such as service release, application release, etc. For this kind of rollback, the current version of the data is generally not deleted, but is set to a special state. The next time you edit the previous version, the generated version is not +1, but +2 or even +n, and you have to check the library again, which is troublesome.
So if you don't have special needs, you don't need to do the released rollback, it will bring a lot of complexity.
about the author
I'm Yasin, a techie who loves to blog
WeChat public account: compiled a program (blgcheng)
Personal website: https://yasinshaw.com
Welcome to pay attention to this public number