Как создать собственный уникальный, правильно сформированный и читаемый UID для SQL (кортежи)
Иногда нам всем нужен правильно сформированный идентификатор вместо использования автоматически сгенерированного по умолчанию последовательного целочисленного уникального идентификатора SQL.
iorta_demo=# SELECT * FROM kpi_fields;
id | field_name | status | created_at
----+------------------------------------+--------+----------------------------
11 | Total GWP in ₹ Lac | 1 | 2022-11-30 23:24:23.113146
12 | Total GWP Retention in ₹ | 1 | 2022-11-30 23:25:01.880207
13 | % Issuance | 1 | 2022-11-30 23:25:14.208774
14 | Issuance % | 1 | 2022-11-30 23:25:57.056154
15 | Issuance | 1 | 2022-11-30 23:26:38.292793
16 | Pendancy(GWP Pendancy vs. GWP Ach) | 1 | 2022-11-30 23:26:54.969397
17 | Pendancy | 1 | 2022-11-30 23:28:05.264689
(7 rows)
Но я не хочу использовать автоматически сгенерированный серийный номер. Итак, сначала мы создадим шаблон идентификатора для образца.
Итак, предположим, что у нас есть таблица агентов со столбцами типа (agent_id, first_name и last_name), эти столбцы я выбираю для примера.
Каждый агент будет иметь уникальный идентификатор агента.
Формула : Инициалы+год(last_two_no's)+месяц(01..09, 10, 11, 12)+счетчик(0000)
пример: AG22120001
Концепция :
AG — это код, обозначающий агента(ов).
Год и месяц — используется для целей комбинаций, что означает, что мы можем создать большой набор комбинаций для идентификаторов агентов.
Примечание . Используйте последний месяц и последние годы.
Счетчик : я использую счетчик 0000 (4 цифры). Счетчик будет увеличиваться на +1 каждый раз при создании нового агента.
Примеры : 0001…0009…0010…0099…0100…0999…1000
Примечание . Счетчик будет сброшен, когда начнется новый месяц. Это означает, что если текущий месяц - декабрь (12), и когда начинается январь, система автоматически сбрасывает счетчик.
Month(12) -> 0100 — останавливаем инкремент, если месяц изменился
Месяц(01) -> 0000 — счетчик снова начнет с 0
Итак, как это выглядит,
AG22120100 — декабрь прошлого года — 2022
AG23010001 — на новый месяц январь — 2023.
Когда начнется февраль (02)-2023 , счетчик снова будет сброшен.
Я надеюсь, вы понимаете мою точку зрения. давайте попробуем добиться этого с помощью Javascript.
Алгоритм:
Algorithm
1) D <- new Date()
2) latest_year <- D.getFullYear()
3) latest_month <- D.getMonth() + 1
4) last_index <- obj.last_updated_index
5) month <- obj.month
6) IF latest_month == month THEN
last_index <- last_index + 1
ELSE
// Reset indexing for new month
last_index <- 1;
7) // append 0 if month is single digit
latest_month = latest_month < 10 ? '0'+latest_month : latest_month
8) // handle 4 digit counter using condition
IF last_index < 10 THEN
last_index = '000'+last_index
ELSE IF last_index >= 10 AND last_index < 100 THEN
last_index = '00'+last_index
ELSE IF last_index >= 100 && last_index < 1000 THEN
last_index = '0'+last_index
9) // Remove first 2 digit from year
latest_year = latest_year.toString().slice(2);
10) // Combine all in a single string
id <- AG+latest_year+latest_month+last_index;
Теперь ниже исходный код, пожалуйста, попробуйте понять код.
// Initialization is required
let cache = {
last_updated_index: 1,
month: 12 // I used current month
};
function generateUID() {
let _calendar_ = new Date();
let latest_year = _calendar_.getFullYear();
let latest_month = _calendar_.getMonth() + 1;
let last_index = cache.last_updated_index;
let month = cache.month;
if (latest_month === month) {
last_index = last_index + 1;
} else {
cache.month = latest_month;
cache.last_updated_index = 1;
last_index = 1;
}
latest_month = latest_month < 10 ? '0' + latest_month : latest_month;
if (last_index < 10) {
last_index = '000' + last_index
} else if (last_index >= 10 && last_index < 100) {
last_index = '00' + last_index
} else if (last_index >= 100 && last_index < 1000) {
last_index = '0' + last_index
}
latest_year = latest_year.toString().slice(2);
return 'AG' + latest_year + latest_month + last_index;
}
let txt = '';
// this loop is just for testing, or demonstration
for (let i = 0; i < 10; i++) {
let i = generateUID();
cache.last_updated_index += 1;
txt += i + " | "
}
console.log(txt);
/* Output
AG22120001
AG22120002
AG22120003
AG22120004
AG22120005
AG22120006
AG22120007
AG22120008
AG22120009
AG22120010
*/
Требование: создайте две таблицы: 1) агенты и 2) «uid». Я использую PostgreSQL для демонстрации.
-- uid for storing last index - like a cache
CREATE TABLE uid(
last_index INT,
current_month INT,
last_updated TIMESTAMP
);
INSERT INTO uid (last_index, current_month, last_updated)
VALUES (1, 12, current_timestamp)
SELECT * FROM uid;
last_index | current_month | last_updated
------------+---------------+----------------------------
1 | 12 | 2022-12-03 22:10:03.746067
(1 row)
-- Agent table
CREATE TABLE agents(
agent_id VARCHAR(10) PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50)
);
const express = require('express');
const bodyParser = require('body-parser');
const app = express();
const Pool = require('pg').Pool
const pool = new Pool({
user: 'postgres',
host: 'localhost',
database: '<YOUR_DB_NAME>',
password: '<YOUR_PASSWORD>',
port: 5432,
})
app.use(bodyParser.json());
app.use(
bodyParser.urlencoded({
extended: true,
})
);
app.post('/add-agent', (req, res) => {
let first_name = req.body.firstName;
let last_name = req.body.lastName;
// You can create seprate file for that
pool.query('SELECT * FROM uid', (error, result) => {
if (error) {
console.log("Error ", error)
res.status(500).send({
CODE: 'ERROR',
TXT: error.message
});
return;
}
let _calendar_ = new Date();
let latest_year = _calendar_.getFullYear();
let latest_month = _calendar_.getMonth() + 1;
let last_index = result.rows[0].last_index;
let month = result.rows[0].current_month;
if (month == latest_month) {
last_index += 1;
} else {
const updateQuery = `UPDATE uid SET current_month = ${latest_month}, last_index = 1`;
pool.query(updateQuery, (error) => {
if (!error) {
console.log("UID is updated successfully");
} else {
console.error(error.stack)
}
});
last_index = 1;
}
latest_month = latest_month < 10 ? '0' + latest_month : latest_month;
if (last_index < 10) {
last_index = '000' + last_index
} else if (last_index >= 10 && last_index < 100) {
last_index = '00' + last_index
} else if (last_index >= 100 && last_index < 1000) {
last_index = '0' + last_index
}
latest_year = latest_year.toString().slice(2);
// =========================== please try to seprate it=============
let newAgentID = 'AG' + latest_year + latest_month + last_index;
const insertQuery = `
INSERT INTO agents(
agent_id,
first_name,
last_name
) VALUES ($1, $2, $3)
RETURNING *;
`;
pool.query(insertQuery, [
newAgentID,
first_name,
last_name
], (error, result) => {
if (error) {
console.error(error.stack)
res.status(500).send({
CODE: 'ERROR',
TXT: error.message
});
} else {
const updateQuery = `UPDATE uid SET last_index = last_index + 1`;
pool.query(updateQuery, (error) => {
if (!error) {
console.log("UID is updated successfully")
} else {
console.error(error.stack)
}
});
res.status(200).send({
CODE: 'SUCCESS',
TXT: result.rows
});
}
});
})
});
const PORT = 5025;
app.listen(PORT, () => {
console.log("Server started successfully on " + PORT);
})
curl --location --request POST '127.0.0.1:5025/add-agent' \
--header 'Content-Type: application/json' \
--data-raw '{
"firstName": "jon",
"lastName": "smith"
}'
SELECT * FROM agents;
agent_id | first_name | last_name
------------+------------+-----------
AG22120002 | rahul | soni
AG22120003 | pankaj | k
AG22120004 | jon | smith
(3 rows)
-- uid table
SELECT * FROM uid;
last_index | current_month | last_updated
------------+---------------+----------------------------
4 | 12 | 2022-12-03 22:10:03.746067
(1 row)