Ich habe eine Tabelle namens „Client“, die von Eingaben aus anderen Tabellen abhängt. Mit den folgenden Spezifikationen:
crewdb=#\d+ client;
Table "public.client"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
---------------------+---------+-----------+----------+------------------------------+----------+--------------+-------------
clientid | integer | | not null | generated always as identity | plain | |
account_name | text | | not null | | extended | |
last_name | text | | | | extended | |
first_name | text | | | | extended | |
address | text | | not null | | extended | |
suburbid | integer | | | | plain | |
cityid | integer | | | | plain | |
post_code | integer | | not null | | plain | |
business_phone | text | | | | extended | |
home_phone | text | | | | extended | |
mobile_phone | text | | | | extended | |
alternative_phone | text | | | | extended | |
email | text | | | | extended | |
quote_detailsid | integer | | | | plain | |
invoice_typeid | integer | | | | plain | |
payment_typeid | integer | | | | plain | |
job_typeid | integer | | | | plain | |
communicationid | integer | | | | plain | |
accessid | integer | | | | plain | |
difficulty_levelid | integer | | | | plain | |
current_lawn_price | numeric | | | | main | |
square_meters | numeric | | | | main | |
note | text | | | | extended | |
client_statusid | integer | | | | plain | |
reason_for_statusid | integer | | | | plain | |
Indexes:
"client_pkey" PRIMARY KEY, btree (clientid)
"account_name_check" UNIQUE CONSTRAINT, btree (account_name)
Foreign-key constraints:
"client_accessid_fkey" FOREIGN KEY (accessid) REFERENCES access(accessid)
"client_cityid_fkey" FOREIGN KEY (cityid) REFERENCES city(cityid)
"client_client_statusid_fkey" FOREIGN KEY (client_statusid) REFERENCES client_status(client_statusid)
"client_communicationid_fkey" FOREIGN KEY (communicationid) REFERENCES communication(communicationid)
"client_difficulty_levelid_fkey" FOREIGN KEY (difficulty_levelid) REFERENCES difficulty_level(difficulty_levelid)
"client_invoice_typeid_fkey" FOREIGN KEY (invoice_typeid) REFERENCES invoice_type(invoice_typeid)
"client_job_typeid_fkey" FOREIGN KEY (job_typeid) REFERENCES job_type(job_typeid)
"client_payment_typeid_fkey" FOREIGN KEY (payment_typeid) REFERENCES payment_type(payment_typeid)
"client_quote_detailsid_fkey" FOREIGN KEY (quote_detailsid) REFERENCES quote_details(quote_detailsid)
"client_reason_for_statusid_fkey" FOREIGN KEY (reason_for_statusid) REFERENCES reason_for_status(reason_for_statusid)
"client_suburbid_fkey" FOREIGN KEY (suburbid) REFERENCES suburb(suburbid)
Referenced by:
TABLE "work" CONSTRAINT "work_clientid_fkey" FOREIGN KEY (clientid) REFERENCES client(clientid)
Die Spalte „Client-ID“ (Primärschlüssel) ist nicht in der richtigen Reihenfolge, da Clientdatensätze wie folgt gelöscht wurden:
crewdb=# select clientid from client order by clientid asc limit 22;
clientid
----------
2
3
4
5
6
7
8
9
10
11
12
13
14
15
17
19
21
22
23
24
26
30
(22 rows)
zB wurden Zeile 1 und 25 gelöscht. Gibt es eine Möglichkeit, den Index von 1 Schritt für Schritt neu zu starten, wobei die Beziehungen zu anderen Tabellen berücksichtigt werden und das alles auf sichere Weise?
Antwort1
Haftungsausschluss: Im Prinzip gefällt mir die Idee, schöne und saubere IDs zu haben. Die Neunummerierung bringt jedoch keinen Vorteil, wenn sie erfolgreich ist, während sie die Datenbank zerstört, wenn sie fehlschlägt.
Zunächst sollten Sie sich vergewissern, dass Sie dereinziger Benutzer, der mit der Datenbank verbunden ist. Wir werden trotzdem Transaktionen verwenden, aber dadurch kann die Datenbank ihre Arbeit schneller erledigen.
Bevor Sie die client
Tabelle neu nummerieren, müssen Sie die FOREIGN KEY
Einschränkungen ändern, die auf die Tabelle verweisen:
Referenced by: TABLE "work" CONSTRAINT "work_clientid_fkey" FOREIGN KEY (clientid) REFERENCES client(clientid)
und füge die CASCADE
Aktion hinzu ON UPDATE
(vgl.CREATE TABLE-Referenz):
BEGIN;
ALTER TABLE work DROP CONSTRAINT work_clientid_fkey;
ALTER TABLE work ADD CONSTRAINT work_clientid_fkey
FOREIGN KEY (clientid) REFERENCES client ON UPDATE CASCADE;
COMMIT;
work.clientid
Dadurch wird die Spalte automatisch aktualisiert , wenn sich die client.clientid
Spalte ändert. Wenn dies erledigt ist, können wir eine SELECT
Anweisung verwenden, um die neuen IDs zu generieren und das Ergebnis verwenden, um eine UPDATE
Anweisung auszugeben, wiein dieser Antwort erklärt. Sie können dies tun mit:
BEGIN;
CREATE SEQUENCE temp_client_id;
-- The real work begins
UPDATE client
SET clientid = ids.new_id
FROM (SELECT clientid AS old_id, nextval('temp_client_id') AS new_id
FROM client ORDER BY clientid) AS ids
WHERE clientid = ids.old_id;
-- Clean up
DROP SEQUENCE temp_client_id;
COMMIT;
Nachdem dies alles erledigt ist, möchten Sie möglicherweise den Wert der Sequenz aktualisieren, die Sie zum Generieren von IDs für die client
Tabelle verwenden (nennen wir sie client_id_seq
):
SELECT setval('client_id_seq', MAX(clientid)) FROM client;