Tengo una tabla llamada cliente que depende de la entrada de otras tablas. con las siguientes especificaciones:
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)
La columna clientid (clave principal) está desordenada ya que los registros de clientes se eliminaron de la siguiente manera:
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)
por ejemplo, se eliminaron las filas 1 y 25. ¿Hay alguna manera de reiniciar el índice desde 1 incremento en 1 teniendo en cuenta las relaciones con otras tablas y haciendo todo eso de manera segura?
Respuesta1
Descargo de responsabilidad: En principio, me gusta la idea de tener identificadores bonitos y limpios. Sin embargo, renumerarlos no ofrece ninguna ventaja si tiene éxito, mientras que dañará la base de datos si falla.
Primero es mejor asegurarse usted mismo, que usted es elúnico usuario conectado a la base de datos. Usaremos transacciones de todos modos, pero eso ayudará a que la base de datos haga su trabajo más rápido.
Antes de volver a numerar la client
tabla, debe cambiar las FOREIGN KEY
restricciones que hacen referencia a la tabla:
Referenced by: TABLE "work" CONSTRAINT "work_clientid_fkey" FOREIGN KEY (clientid) REFERENCES client(clientid)
y añadir la CASCADE
acción a ON UPDATE
(cf.CREAR TABLA de referencia):
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;
Esto actualizará automáticamente la work.clientid
columna cuando ésta client.clientid
cambie. Cuando se hace esto, podemos usar una SELECT
declaración para generar los nuevos identificadores y usar el resultado para emitir una UPDATE
declaración, comoexplicado en esta respuesta. Puedes hacerlo con:
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;
Una vez hecho todo esto, es posible que desees actualizar el valor de la secuencia que estás utilizando para generar identificadores para la client
tabla (llamémosla client_id_seq
):
SELECT setval('client_id_seq', MAX(clientid)) FROM client;