当前位置:网站首页>Unique primary key ID of tidb sub table -- solution to failure of sequence and Gorm to obtain primary key
Unique primary key ID of tidb sub table -- solution to failure of sequence and Gorm to obtain primary key
2022-04-23 05:05:00 【canger_】
It's reasonable to use TiDB After that, you don't have to consider the problem of sub database and sub table , Business scenarios should also be supported MySQL, And there is indeed some isolation in the data , Therefore, the horizontal table is divided by data type .
MySQL The primary key after horizontal table splitting id adopt snowflake To write , and TiDB Primary key of id Decide to pass tidb Of sequenceID To achieve
Sequence
Sequence It is the number sequence that the database system increases itself according to certain rules , Having unique and monotonically increasing properties . In the official SQL 2003 In the standard , It is defined as " A mechanism for generating continuous values ,Sequence It can be either an internal object , It can also be an external object ". Because native MySQL Not supported in Sequence, therefore TiDB Sequence The grammar of MariaDB、Oracle and IBM Db2
- Create Sequence grammar
CREATE [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name
[ INCREMENT [ BY | = ] INCREMENT ]
[ MINVALUE [=] minvalue | NO MINVALUE | NOMINVALUE ]
[ MAXALUE [=] maxvalue | NO MAXVALUE | NOMAXVALUE ]
[ START [ WITH | = ] start ]
[ CACHE [=] cache | NOCACHE | NO CACHE]
[ CYCLE | NOCYCLE | NO CYCLE]
[ ORDER | NOORDER | NO ORDER]
[table_options]
- Show Create Sequence grammar
SHOW CREATE SEQUENCE sequence_name
- Drop Sequence
DROP [TEMPORARY] SEQUENCE [IF NOT EXISTS] sequence_name
- Get the next value
SELECT NEXT VALUE FOR sequence_name;
SELECT NEXTVAL(sequence_name);
Example
Create three tables with the same structure , The table is divided into tables according to business types
CREATE SEQUENCE seq_for_autoid START WITH 1 INCREMENT BY 1 CACHE 1000 NOCYCLE;
SHOW CREATE SEQUENCE seq_for_autoid;
CREATE TABLE `user_1` (
`autoid` int(11) DEFAULT nextval(seq_for_autoid),
`userid` varchar(32) NOT NULL,
PRIMARY KEY (`autoid`)
);
CREATE TABLE user_2 LIKE user_1;
CREATE TABLE user_3 LIKE user_1;
- Insert the test
INSERT INTO user_1(userid) VALUES ('a1'),('b1'),('c1'),('d1'),('e1'),('f1');
INSERT INTO user_2(userid) VALUES ('a1'),('b1'),('c1'),('d1'),('e1'),('f1');
INSERT INTO user_3(userid) VALUES ('a1'),('b1'),('c1'),('d1'),('e1'),('f1');
user_1 surface :

user_2 surface :

user_3 surface :

gorm Batch insert interface for , Unable to return the obtained primary key value
import (
"github.com/sirupsen/logrus"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
)
type User_1 struct {
AutoId int `gorm:"column:autoid;primarykey"`
UserId string `gorm:"column:userid"`
}
func main() {
db, err := gorm.Open(mysql.Open("test:test@tcp(127.0.0.1:4000)/apiserver?charset=utf8mb4&parseTime=true&loc=Local")})
if err != nil {
return
}
var users []User_1
users = append(users, User_1{
UserId: "6"})
users = append(users, User_1{
UserId: "7"})
users = append(users, User_1{
UserId: "8"})
users = append(users, User_1{
UserId: "9"})
users = append(users, User_1{
UserId: "10"})
db.Debug().Create(&users)
logrus.Info(users)
}
// Running results
[14.247ms] [rows:5] INSERT INTO `user_1` (`userid`) VALUES ('6'),('7'),('8'),('9'),('10')
time="2022-04-20T16:47:57+08:00" level=info msg="[{0 6} {0 7} {0 8} {0 9} {0 10}]"
- resolvent 1: Write a BeforeCreate Hook function
func (user *User_1) BeforeCreate(tx *gorm.DB) error {
var sequenceId uint
if err := tx.Raw("SELECT NEXT VALUE FOR seq_for_autoid;").First(&sequenceId).Error; err != nil {
return err
}
user.AutoId = sequenceId
return nil
}
func main() {
db, err := gorm.Open(mysql.Open("test:test@tcp(127.0.0.1:4000)/apiserver?charset=utf8mb4&parseTime=true&loc=Local"), &gorm.Config{
NamingStrategy: schema.NamingStrategy{
SingularTable: false,
},
})
if err != nil {
return
}
//db.AutoMigrate(&User{})
var users []User_1
users = append(users, User_1{
UserId: "aaa"})
users = append(users, User_1{
UserId: "bbb"})
db.Debug().Table("user_1").Create(&users)
db.Debug().Table("user_2").Create(&users)
db.Debug().Table("user_3").Create(&users)
logrus.Info(users)
}
// Execution results , But every time you insert select once , It's slow when you write frequently
[1.288ms] [rows:1] SELECT NEXT VALUE FOR seq_for_autoid;
[0.999ms] [rows:1] SELECT NEXT VALUE FOR seq_for_autoid;
[15.168ms] [rows:2] INSERT INTO `user_3` (`userid`,`autoid`) VALUES ('aaa',48),('bbb',49)
time="2022-04-20T17:24:14+08:00" level=info msg="[{48 aaa} {49 bbb}]"
- resolvent 2: Query after batch insertion last_sequence
This method only needs to be queried once , But inserts and queries lastId Be sure to put it in the same transaction , Otherwise, it will lead to lastid Get exception
func main() {
var users []User
users = append(users, User{
UserId: "oopoo"})
users = append(users, User{
UserId: "nomonno"})
var lastId uint64
if err = db.Debug().Transaction(func(tx *gorm.DB) error {
if err := tx.Table("user_1").Create(&users).Error; err != nil {
return err
}
// This step queries the last one inserted last time sequence_id
if err := tx.Raw("SELECT lastval(seq_for_autoid);").First(&lastId).Error; err != nil {
return err
}
// Manual assignment
for i := 0; i < len(users); i++ {
users[len(users)-i-1].AutoId = uint(lastId) - uint(i)
}
return nil
}); err != nil {
logrus.Error(err)
return
}
logrus.Info(users)
}
版权声明
本文为[canger_]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204220552063144.html
边栏推荐
- Differences between redis and MySQL
- The vscode ipynb file does not have code highlighting and code completion solutions
- Innovation training (V) configuration information
- MySQL realizes row to column SQL
- View analysis of scenic spots in ArcGIS
- [WinUI3]編寫一個仿Explorer文件管理器
- Get the number of days between dates, get the Chinese date, get the date of the next Monday of the date, get the working day, get the rest day
- js 判斷數字字符串中是否含有字符
- redis数据类型有哪些
- Live delivery form template - automatically display pictures - automatically associate series products
猜你喜欢

Download PDF from HowNet (I don't want to use CAJViewer anymore!!!)

Restful toolkit of idea plug-in

Backup MySQL database with Navicat
![[database] MySQL basic operation (basic operation ~)](/img/0c/a8d858fa74ffed2a266ca77c783c7f.png)
[database] MySQL basic operation (basic operation ~)

《2021多多阅读报告》发布,95后、00后图书消费潜力攀升

Deep learning notes - data expansion

Sword finger offer: the median in the data stream (priority queue large top heap small top heap leetcode 295)
![[database] MySQL multi table query (I)](/img/c7/43167aa6169c24a8d9734032775335.png)
[database] MySQL multi table query (I)

View analysis of scenic spots in ArcGIS

Innovation training (IX) integration
随机推荐
C# List字段排序含有数字和字符
Learning Android from scratch -- Introduction
Golang select priority execution
Mac enters MySQL terminal command
L2-011 play binary tree (build tree + BFS)
Installing kuberneters using kubedm
Unity C e-learning (IV)
MySQL 慢查询
[database] MySQL single table query
2022/4/22
Field injection is not recommended using @ Autowired
静态流水线和动态流水线的区别认识
Logrus set log format and output function name
[database] MySQL multi table query (I)
AQS源码阅读
Deep learning notes - semantic segmentation and data sets
Deep learning notes - data expansion
How can continuous integration (CI) / continuous delivery (CD) revolutionize automated testing
The WebService interface writes and publishes calls to the WebService interface (2)
2022/4/22