Postgresql 10 - 다른 테이블에 의존하는 테이블의 기본 키 열 순서를 다시 지정하는 방법

Postgresql 10 - 다른 테이블에 의존하는 테이블의 기본 키 열 순서를 다시 지정하는 방법

다른 테이블의 입력에 의존하는 클라이언트라는 테이블이 있습니다. 다음 사양을 사용합니다.

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)

clientid(기본 키) 열은 다음과 같이 삭제된 클라이언트 레코드의 순서가 잘못되었습니다.

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)

예를 들어 행 1과 25가 삭제되었습니다. 다른 테이블과의 관계를 고려하고 안전한 방식으로 모든 작업을 수행하면서 1씩 1씩 인덱스를 다시 시작하는 방법이 있습니까?

답변1

부인 성명: 원칙적으로 나는 ID가 깔끔하고 깨끗하다는 생각을 좋아합니다. 그러나 번호를 다시 매기는 것은 성공하더라도 이점이 없으며, 실패하면 데이터베이스가 손상됩니다.

먼저 자신이 누구인지 확인하는 것이 좋습니다.데이터베이스에 연결된 유일한 사용자. 어쨌든 우리는 트랜잭션을 사용할 것이지만 이는 데이터베이스가 작업을 더 빠르게 수행하는 데 도움이 될 것입니다.

테이블 번호를 다시 매기기 전에 테이블을 참조하는 제약 조건을 client변경해야 합니다 .FOREIGN KEY

Referenced by: TABLE "work" CONSTRAINT "work_clientid_fkey" FOREIGN KEY (clientid) REFERENCES client(clientid)

그리고 ( CASCADEcf.ON UPDATECREATE TABLE 참조):

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열이 변경 되면 자동으로 열이 업데이트됩니다 client.clientid. 이 작업이 완료되면 명령문을 사용 SELECT하여 새 ID를 생성하고 결과를 사용하여 UPDATE다음과 같이 명령문을 발행할 수 있습니다.이 답변에 설명되어 있습니다. 다음을 사용하여 수행할 수 있습니다.

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;

이 모든 작업이 완료되면 테이블의 ID를 생성하는 데 사용하는 시퀀스의 값을 업데이트할 수 있습니다 client(라고 부르겠습니다 client_id_seq).

SELECT setval('client_id_seq', MAX(clientid)) FROM client;

관련 정보