هل من الممكن تغيير الترتيب الطبيعي للأعمدة في Postgres؟

StackOverflow https://stackoverflow.com/questions/126430

  •  02-07-2019
  •  | 
  •  

سؤال

هل من الممكن تغيير الترتيب الطبيعي للأعمدة في Postgres 8.1؟

أعلم أنه لا ينبغي عليك الاعتماد على ترتيب الأعمدة - فهو ليس كذلك ضروري إلى ما أفعله - أحتاجه فقط لجعل بعض الأشياء التي تم إنشاؤها تلقائيًا تظهر بطريقة أكثر إرضاءً، بحيث يتطابق الترتيب الميداني على طول الطريق من pgadmin عبر النهاية الخلفية وخارجًا إلى الواجهة الأمامية.

هل كانت مفيدة؟

المحلول

يمكنك في الواقع تغيير ترتيب الأعمدة بشكل مباشر، لكنني لا أوصي بذلك، ويجب أن تكون حذرًا للغاية إذا قررت القيام بذلك.

على سبيل المثال.

# CREATE TABLE test (a int, b int, c int);
# INSERT INTO test VALUES (1,2,3);
# SELECT * FROM test;
 a | b | c 
---+---+---
 1 | 2 | 3
(1 row)

الآن بالنسبة للجزء الصعب، تحتاج إلى الاتصال بقاعدة البيانات الخاصة بك باستخدام مستخدم postgres حتى تتمكن من تعديل جداول النظام.

# SELECT relname, relfilenode FROM pg_class WHERE relname='test';
 relname | relfilenode 
---------+-------------
 test_t  |       27666
(1 row)

# SELECT attrelid, attname, attnum FROM pg_attribute WHERE attrelid=27666;
 attrelid | attname  | attnum 
----------+----------+--------
    27666 | tableoid |     -7
    27666 | cmax     |     -6
    27666 | xmax     |     -5
    27666 | cmin     |     -4
    27666 | xmin     |     -3
    27666 | ctid     |     -1
    27666 | b        |      1
    27666 | a        |      2
    27666 | c        |      3
(9 rows)

attnum هو عمود فريد، لذلك تحتاج إلى استخدام قيمة مؤقتة عند تعديل أرقام الأعمدة على هذا النحو:

# UPDATE pg_attribute SET attnum=4 WHERE attname='a' AND attrelid=27666;
UPDATE 1
# UPDATE pg_attribute SET attnum=1 WHERE attname='b' AND attrelid=27666;
UPDATE 1
# UPDATE pg_attribute SET attnum=2 WHERE attname='a' AND attrelid=27666;
UPDATE 1

# SELECT * FROM test;
 b | a | c 
---+---+---
 1 | 2 | 3
(1 row)

مرة أخرى، نظرًا لأن هذا يعد بمثابة تلاعب بجداول نظام قاعدة البيانات، فاستخدم الحذر الشديد إذا كنت تشعر أنك بحاجة حقًا إلى القيام بذلك.

يعمل هذا اعتبارًا من postgres 8.3، مع الإصدارات السابقة، قد يختلف عدد الأميال الخاصة بك.

نصائح أخرى

إذا لم تكن قاعدة بياناتك كبيرة جدًا ويمكنك تحمل بعض فترات التوقف عن العمل، فيمكنك:

  1. تعطيل حق الوصول للكتابة إلى قاعدة البيانات
    يعد هذا أمرًا ضروريًا وإلا فسيتم فقدان أي تغييرات بعد بدء النقطة التالية
  2. pg_dump --create --column-inserts databasename > databasename.pgdump.sql
  3. تحرير المناسب CREATE TABLE البيان في اسم قاعدة البيانات.pgdump.sql
    إذا كان الملف كبيرًا جدًا بالنسبة للمحرر الخاص بك، فما عليك سوى تقسيمه باستخدامه split الأمر، تحرير، ثم تجميع مرة أخرى باستخدام cat
  4. drop database databasename
    لديك نسخة احتياطية حديثة، فقط في حالة، أليس كذلك؟
  5. psql --single-transaction -f databasename.pgdump.sql
    إذا كنت لا تستخدم --single-transaction سيكون بطيئا جدا

إذا كنت تستخدم ما يسمى بالكائنات الكبيرة، فتأكد من تضمينها في ملف التفريغ.لست متأكدًا مما إذا كانوا موجودين افتراضيًا في الإصدار 8.1.

لقد طرحت هذا السؤال في pgsql-admin في عام 2007.أعلن توم لين نفسه أنه من غير الممكن عملياً تغيير الترتيب في الكتالوجات.

إيضاح:للمستخدمين، مع الأدوات الحالية.لا يعني أنه لا يمكن تنفيذه.المنظمة البحرية الدولية، ينبغي أن يكون.
لا يزال صحيحًا بالنسبة لـ Postgres 11.

كما ذكرت الإجابات الأخرى، لا يمكنك تغيير ترتيب الأعمدة، الأمر متروك لـ postgres.يمكنك (ويجب عليك!) حل مشكلتك من خلال طريقة عرض.ولأغراض الاستعلام عن التقارير، سيبدو مثل الجدول تمامًا.شيء مثل:

create view my_view as
  select * from my_table
  order by some_col;

يعد تحديد ترتيب الأعمدة في الاستعلام هو الطريقة الوحيدة الموثوقة (والمعقولة)..ومع ذلك، يمكنك عادةً الحصول على ترتيب مختلف عن طريق تغيير الجدول كما هو موضح في المثال أدناه حيث يتم عادةً (ليس من المضمون) إرجاع الأعمدة بالترتيب الذي تمت إضافتها إلى الجدول.

postgres=# create table a(a int, b int, c int);
CREATE TABLE
postgres=# insert into a values (1,2,3);
INSERT 0 1
postgres=# select * from a;
 a | b | c
---+---+---
 1 | 2 | 3
(1 row)

postgres=# alter table a add column a2 int;
ALTER TABLE
postgres=# select * from a;
 a | b | c | a2
---+---+---+----
 1 | 2 | 3 |
(1 row)

postgres=# update a set a2 = a;
UPDATE 1
postgres=# alter table a drop column a;
ALTER TABLE
postgres=# alter table a rename column a2 to a;
ALTER TABLE
postgres=# select * from a;
 b | c | a
---+---+---
 2 | 3 | 1
(1 row)

postgres=#

لسوء الحظ، لا، ليس كذلك.ترتيب العمود متروك تمامًا لـ Postgres.

يمكنك الحصول على ترتيب الأعمدة الذي تريده عن طريق إنشاء جدول جديد وتحديد أعمدة الجدول القديم بالترتيب الذي تريد عرضه به:

CREATE TABLE test_new AS SELECT b, c, a FROM test;
SELECT * from test_new;
 b | c | a 
---+---+---
 2 | 3 | 1
(1 row)

لاحظ أن هذا ينسخ البيانات فقط، وليس المعدلات أو القيود أو الفهارس وما إلى ذلك.

بمجرد تعديل الجدول الجديد بالطريقة التي تريدها، قم بإسقاط الجدول الأصلي وتغيير اسم الجدول الجديد:

BEGIN;
DROP TABLE test;
ALTER TABLE test_new RENAME TO test;
COMMIT;

أريد نفس الشيء.نعم، اطلبه الآن ضروريًا، لكنه يفركني بطريقة خاطئة :)

ما أفعله لحلها هو كما يلي.

ستضمن لك هذه الطريقة الاحتفاظ بأي بيانات موجودة،

  1. قم بإنشاء نسخة جديدة من الجدول باستخدام الترتيب الذي أريده، باستخدام اسم مؤقت.
  2. أدخل كافة البيانات في هذا الجدول الجديد من الجدول الموجود.
  3. إسقاط الجدول القديم.
  4. أعد تسمية الجدول الجديد إلى "الاسم الصحيح" من "الاسم المؤقت".
  5. أعد إضافة أية فهارس كانت لديك سابقًا.
  6. إعادة تعيين تسلسل المعرف لزيادات المفتاح الأساسي.

ترتيب الجدول الحالي:

id, name, email

1.قم بإنشاء نسخة جديدة من الجدول باستخدام الترتيب الذي أريده، باستخدام اسم مؤقت.

في هذا المثال أريد email ليكون من قبل name.

CREATE TABLE mytable_tmp
(
  id SERIAL PRIMARY KEY,
  email text,
  name text
);

2.أدخل كافة البيانات في هذا الجدول الجديد من الجدول الموجود.

INSERT INTO mytable_tmp   --- << new tmp table
(
  id
, email
, name
)
SELECT
  id
, email
, name
FROM mytable;  --- << this is the existing table

3.إسقاط الجدول القديم.

DROP TABLE mytable;

4.أعد تسمية الجدول الجديد إلى "الاسم الصحيح" من "الاسم المؤقت".

ALTER TABLE mytable_tmp RENAME TO mytable;

5.أعد إضافة أية فهارس كانت لديك سابقًا.

CREATE INDEX ...

6.إعادة تعيين تسلسل المعرف لزيادات المفتاح الأساسي.

SELECT setval('public.mytable_id_seq', max(id)) FROM mytable;
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top