PostgreSQL'de tablo CREATE TABLE ad (sütun tip [DEFAULT ifade] [kısıt], ...); ile oluşturulur, yapısı ALTER TABLE ile değiştirilir: ADD COLUMN sütun ekler, DROP COLUMN siler, ALTER COLUMN ... TYPE ... USING tipi dönüştürür, RENAME yeniden adlandırır. Tabloyu tamamen kaldırmak için DROP TABLE, yapıyı koruyup bütün satırları hızla silmek için TRUNCATE kullanılır. PostgreSQL 18 ile üretilmiş sütunlar (GENERATED ALWAYS AS) varsayılan olarak sanaldır, yani okunurken hesaplanır.
Bu yazıda kılavuzun Data Definition bölümündeki tablo temelleri, varsayılan değerler, üretilmiş sütunlar ve tablo değiştirme sayfalarını, CREATE TABLE, ALTER TABLE, DROP TABLE ve TRUNCATE başvuru sayfalarındaki ayrıntılarla birleştiriyoruz. Kısıtlar primary key ve foreign key, tip seçimi veri tipleri, identity sütunları identity ve sequence yazısında. Örnekler PostgreSQL 18.1'de ornek_tablo veritabanında çalıştırıldı; serinin geri kalanı PostgreSQL öğrenme rehberi sayfasında. Çıktılarda yer kazanmak için CREATE ve INSERT gibi komutların onay satırlarını yer yer çıkardık; sorgu sonuçları ve hata mesajları olduğu gibidir.
Tablo temelleri ve adlandırma
Belgeye göre bir tablo kâğıt üzerindeki tablo gibidir: sütunların sayısı ve sırası sabittir, satır sayısı değişkendir. SQL satırların sırası hakkında hiçbir garanti vermez; sıra istiyorsanız sorguda açıkça ORDER BY yazmanız gerekir. SQL satırlara kendiliğinden benzersiz kimlik de atamaz, bu yüzden tamamen aynı iki satır bir tabloda bulunabilir; bunu önlemenin yolu birincil anahtardır. Bir tablonun alabileceği sütun sayısı, sütun tiplerine bağlı olarak 250 ile 1600 arasındadır ve belge buna yakın sayıda sütunu sorgulanabilir bir tasarım olarak görmez.
Tablo ve sütun adları SQL tanımlayıcısıdır. Tırnaksız adlar küçük harfe çevrilir, çift tırnaklı adlar ise büyük/küçük harfe duyarlı olur; en fazla 63 bayt kullanılır, uzun adlar kesilir. Bu kural en sık şaşırtan davranışlardan biridir:
CREATE TABLE "Siparis" (Id integer, "Tutar" numeric);
SELECT * FROM Siparis;
SELECT id, "Tutar" FROM "Siparis";psql:tb2.sql:26: ERROR: relation "siparis" does not exist
LINE 1: SELECT * FROM Siparis;
^
id | Tutar
----+-------
(0 rows)Tabloyu tırnakla "Siparis" olarak oluşturduğumuz için tırnaksız Siparis küçük harfe çevrilip siparis olarak arandı ve bulunamadı. Tırnaksız yazılan Id sütunu ise id olarak kaydedildi. Belgenin önerisi tutarlı olmaktır: bir adı ya her zaman tırnakla ya hiç tırnaksız kullanın. En sorunsuz yol küçük harf, rakam ve alt çizgiden oluşan, tırnak gerektirmeyen adlar seçmektir. Tanımlayıcılar Türkçe harf içerebilir, ama uygulama kodunda ve farklı istemcilerde sorun çıkmaması için örneklerimizde ASCII adlar kullanıyoruz.
CREATE TABLE: sütunlar, varsayılanlar, üretilmiş sütunlar

Aşağıdaki tablo bu yazının ana örneği. Fiyat ve KDV oranı için varsayılan değerler, KDV'li fiyat için sanal, stok değeri için depolanan bir üretilmiş sütun ve ekleme zamanı için now() varsayılanı tanımlıyoruz:
CREATE TABLE urun (
urun_no integer,
ad text NOT NULL,
fiyat numeric(10,2) DEFAULT 0,
kdv_orani numeric(4,2) DEFAULT 20,
kdvli_fiyat numeric GENERATED ALWAYS AS (round(fiyat * (1 + kdv_orani / 100), 2)),
stok_degeri numeric GENERATED ALWAYS AS (fiyat * 10) STORED,
eklenme timestamptz DEFAULT now()
);
INSERT INTO urun (urun_no, ad, fiyat) VALUES (1, 'Çay bardağı', 45.00);
INSERT INTO urun (urun_no, ad, fiyat, kdv_orani) VALUES (2, 'Ekmek', 15.00, 1);
INSERT INTO urun (urun_no, ad) VALUES (3, 'Defter');
SELECT urun_no, ad, fiyat, kdv_orani, kdvli_fiyat, stok_degeri FROM urun ORDER BY urun_no; urun_no | ad | fiyat | kdv_orani | kdvli_fiyat | stok_degeri
---------+-------------+-------+-----------+-------------+-------------
1 | Çay bardağı | 45.00 | 20.00 | 54.00 | 450.00
2 | Ekmek | 15.00 | 1.00 | 15.15 | 150.00
3 | Defter | 0.00 | 20.00 | 0.00 | 0.00
(3 rows)DEFAULT nasıl çalışır?
Varsayılan değer, bir satır eklenirken o sütun için değer verilmediğinde kullanılır; hiç tanımlanmamışsa varsayılan NULL'dur. Belgenin vurguladığı nokta, varsayılan ifadenin tablo oluşturulurken değil her ekleme sırasında hesaplanmasıdır; now() veya CURRENT_TIMESTAMP varsayılanı bu yüzden her satıra kendi ekleme zamanını yazar. Varsayılan ifadesi başka sütunlara başvuramaz ve alt sorgu içeremez. INSERT ve UPDATE içinde DEFAULT anahtar kelimesiyle bir sütunu açıkça varsayılanına döndürebilirsiniz. Sıra numarası üreten varsayılanlar için belge nextval() ve serial kısayolunu gösterir; günümüzde önerilen standart yol identity sütunlarıdır ve identity, serial ve sequence yazısında ele alınıyor.
Üretilmiş sütunlar: VIRTUAL ve STORED
Üretilmiş sütun, değeri her zaman aynı satırdaki diğer sütunlardan hesaplanan özel bir sütundur. Belge iki türü şöyle karşılaştırır: depolanan (STORED) sütun yazılırken hesaplanır ve normal bir sütun gibi yer kaplar, materialized view'a benzer; sanal (VIRTUAL) sütun hiç yer kaplamaz ve okunurken hesaplanır, view'a benzer. PostgreSQL 18 sürüm notlarına göre sanal üretilmiş sütunlar bu sürümle geldi ve varsayılan oldu; yazma sırasında hesaplanmasını istiyorsanız STORED yazmanız gerekir. Yukarıdaki \d çıktısında bu fark görülür:
\d urun Table "public.urun"
Column | Type | Collation | Nullable | Default
-------------+--------------------------+-----------+----------+---------------------------------------------------------------------------------
urun_no | integer | | |
ad | text | | not null |
fiyat | numeric(10,2) | | | 0
kdv_orani | numeric(4,2) | | | 20
kdvli_fiyat | numeric | | | generated always as (round(fiyat * (1::numeric + kdv_orani / 100::numeric), 2))
stok_degeri | numeric | | | generated always as (fiyat * 10::numeric) stored
eklenme | timestamp with time zone | | | now()Üretilmiş sütuna doğrudan yazılamaz; INSERT veya UPDATE içinde yalnızca DEFAULT verilebilir. Kaynak sütun değiştiğinde her iki tür de yeni değeri yansıtır:
INSERT INTO urun (urun_no, ad, fiyat, kdvli_fiyat) VALUES (4, 'Kalem', 10, 12);
INSERT INTO urun (urun_no, ad, fiyat, kdvli_fiyat) VALUES (4, 'Kalem', 10, DEFAULT);
UPDATE urun SET fiyat = 50 WHERE urun_no = 1;
SELECT urun_no, fiyat, kdvli_fiyat, stok_degeri FROM urun WHERE urun_no = 1;psql:tb1.sql:16: ERROR: cannot insert a non-DEFAULT value into column "kdvli_fiyat"
DETAIL: Column "kdvli_fiyat" is a generated column.
INSERT 0 1
UPDATE 1
urun_no | fiyat | kdvli_fiyat | stok_degeri
---------+-------+-------------+-------------
1 | 50.00 | 60.00 | 500.00
(1 row)Üretim ifadesine belgede sayılan kurallar uygulanır: yalnızca değişmez (immutable) fonksiyonlar kullanılabilir, alt sorgu ve başka tablolara başvuru yasaktır, başka bir üretilmiş sütuna başvurulamaz, üretilmiş sütunun varsayılanı veya identity tanımı olamaz ve bölümleme anahtarının parçası olamaz. Sanal sütunlar için ek kısıt vardır: kullanıcı tanımlı tip olamaz ve ifade yalnızca yerleşik fonksiyon ve tipleri kullanabilir. Zamanı yazmak için now() kullanmayı denediğimizde değişmezlik kuralı devreye girdi:
CREATE TABLE hatali (a int, b timestamptz GENERATED ALWAYS AS (now()));psql:tb1.sql:21: ERROR: generation expression is not immutable| Özellik | DEFAULT | GENERATED VIRTUAL | GENERATED STORED |
|---|---|---|---|
| Ne zaman hesaplanır | Ekleme sırasında bir kez | Her okunuşta | Her yazışta |
| Diskte yer kaplar mı | Evet (değer saklanır) | Hayır | Evet |
| Elle değer verilebilir mi | Evet | Hayır, yalnızca DEFAULT | Hayır, yalnızca DEFAULT |
| Diğer sütunlara başvurabilir mi | Hayır | Evet | Evet |
| now(), random() gibi değişken fonksiyon | Evet | Hayır | Hayır |
| Kullanıcı tanımlı fonksiyon veya tip | Evet | Hayır | Evet (immutable olmalı) |
ALTER TABLE ile yapıyı değiştirmek

Belge, dolu ya da başka nesnelerin başvurduğu bir tabloyu silip yeniden oluşturmanın pratik olmadığını, bu yüzden ALTER TABLE komut ailesinin bulunduğunu belirtir. Bu komutlar tablonun verisini değil tanımını değiştirir. Aşağıda en sık kullanılan biçimleri sırayla deniyoruz.
Sütun eklemek
ALTER TABLE urun ADD COLUMN barkod text;
ALTER TABLE urun ADD COLUMN aktif boolean NOT NULL DEFAULT true;
SELECT urun_no, barkod, aktif FROM urun ORDER BY urun_no; urun_no | barkod | aktif
---------+--------+-------
1 | | t
2 | | t
3 | | t
4 | | t
(4 rows)Yeni sütun mevcut satırlarda varsayılan değerle (verilmemişse NULL ile) dolar. Başvuru sayfasının Notes bölümü büyük tablolar için kritik bir ayrıntı verir: değişken olmayan (non-volatile) bir varsayılanla eklenen sütun için tablo yeniden yazılmaz; değer bir kez hesaplanıp tablo meta verisine kaydedilir ve eski satırlar okunurken döndürülür, bu yüzden komut büyük tablolarda da çok hızlıdır. clock_timestamp() gibi değişken bir varsayılan, depolanan bir üretilmiş sütun, identity sütunu veya kısıtlı bir domain tipi ise bütün tablonun ve indekslerinin yeniden yazılmasına yol açar. Sanal üretilmiş sütun eklemek hiçbir zaman yeniden yazma gerektirmez. Sütunla birlikte kısıt da tanımlanabilir, ancak varsayılan değer kısıtı sağlamıyorsa ekleme başarısız olur:
ALTER TABLE urun ADD COLUMN birim text DEFAULT '' CHECK (birim <> '');psql:tb2.sql:6: ERROR: check constraint "urun_birim_check" of relation "urun" is violated by some rowVeri tipini değiştirmek ve USING
ALTER COLUMN ... TYPE yalnızca mevcut her değer yeni tipe örtük olarak dönüştürülebiliyorsa başarılı olur; daha karmaşık dönüşümler için USING ile yeni değerin eski değerden nasıl hesaplanacağını yazarsınız. Metin olarak tutulmuş ağırlıkları sayıya çevirmeyi denedik:
ALTER TABLE urun ALTER COLUMN urun_no TYPE bigint;
ALTER TABLE urun ADD COLUMN agirlik text;
UPDATE urun SET agirlik = '0.25 kg' WHERE urun_no = 1;
UPDATE urun SET agirlik = '1 kg' WHERE urun_no = 2;
ALTER TABLE urun ALTER COLUMN agirlik TYPE numeric;
ALTER TABLE urun ALTER COLUMN agirlik TYPE numeric USING replace(agirlik, ' kg', '')::numeric;
SELECT urun_no, agirlik FROM urun ORDER BY urun_no;ALTER TABLE
ALTER TABLE
UPDATE 1
UPDATE 1
psql:tb2.sql:12: ERROR: column "agirlik" cannot be cast automatically to type numeric
HINT: You might need to specify "USING agirlik::numeric".
ALTER TABLE
urun_no | agirlik
---------+---------
1 | 0.25
2 | 1
3 |
4 |
(4 rows)Tip değişikliği normalde bütün tablonun ve indekslerinin yeniden yazılması demektir; büyük tablolarda uzun sürer ve geçici olarak iki kat disk alanı gerektirebilir. İstisna, USING değeri değiştirmiyorsa ve eski tip yeni tipe ikili uyumluysa ortaya çıkar; belge örnek olarak collation değişmediği sürece text ile varchar arasında geçişin indeksleri bile yeniden kurmadan yapılabildiğini verir. Belge ayrıca USING ifadesinin sütunun varsayılan değerine uygulanmadığını, bu yüzden dönüşüm başarısız olursa önce DROP DEFAULT, sonra tip değişikliği, en sonda yeni bir SET DEFAULT yapılmasını önerir. Sütuna bağlı kısıtları değişiklikten önce kaldırıp sonra uyarlanmış hâlleriyle eklemek de tavsiye edilir.
Yeniden adlandırma, varsayılanı değiştirme, sütun silme
ALTER TABLE urun RENAME COLUMN agirlik TO agirlik_kg;
ALTER TABLE urun ALTER COLUMN kdv_orani SET DEFAULT 10;
ALTER TABLE urun DROP COLUMN fiyat;
ALTER TABLE urun DROP COLUMN fiyat CASCADE;
ALTER TABLE urun RENAME TO urunler;ALTER TABLE
ALTER TABLE
psql:tb2.sql:18: ERROR: cannot drop column fiyat of table urun because other objects depend on it
DETAIL: column kdvli_fiyat of table urun depends on column fiyat of table urun
column stok_degeri of table urun depends on column fiyat of table urun
HINT: Use DROP ... CASCADE to drop the dependent objects too.
psql:tb2.sql:19: NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to column kdvli_fiyat of table urun
drop cascades to column stok_degeri of table urun
ALTER TABLE
ALTER TABLESET DEFAULT mevcut satırları değiştirmez, yalnızca sonraki eklemeleri etkiler. fiyat sütununu silmek istediğimizde PostgreSQL'in bağımlılık takibi devreye girdi: iki üretilmiş sütun bu sütuna dayandığı için komut reddedildi ve CASCADE ile birlikte o sütunlar da silindi. Belge, sütuna başka bir tablonun yabancı anahtarı başvuruyorsa bu kısıtın da sessizce silinmeyeceğini, CASCADE gerektiğini belirtir. Bir başka önemli not: DROP COLUMN sütunu fiziksel olarak silmez, yalnızca SQL'e görünmez yapar; disk alanı satırlar güncellendikçe zamanla geri kazanılır. Alanı hemen geri almak için tabloyu yeniden yazan bir ALTER TABLE biçimi çalıştırılabilir.
Birden çok değişikliği tek komutta virgülle yazmak mümkündür ve belgeye göre bunun asıl amacı, gereken tablo taramalarını veya yeniden yazmaları tek geçişte birleştirmektir:
ALTER TABLE urunler DROP COLUMN barkod, DROP COLUMN aktif;Üretilmiş sütunlar için de iki özel biçim vardır: ALTER COLUMN ... SET EXPRESSION AS (ifade) üretim ifadesini değiştirir (depolanan sütunlarda mevcut veriyi yeniden yazar), DROP EXPRESSION ise depolanan bir üretilmiş sütunu normal sütuna çevirir; belge bu ikinci biçimin şimdilik yalnızca depolanan sütunlarda desteklendiğini belirtir.
DROP TABLE ve bağımlılıklar
DROP TABLE tabloyu, indekslerini, kurallarını, tetikleyicilerini ve kısıtlarını siler. Tabloya bir view ya da başka bir tablonun yabancı anahtarı başvuruyorsa CASCADE gerekir. Belgedeki ince ayrım şudur: CASCADE bağımlı view'ı tamamen siler, ama yabancı anahtar durumunda yalnızca kısıtı siler, diğer tabloya dokunmaz. Var olmayan bir tabloyu silmek hatadır; betiklerde IF EXISTS bunu bildirime çevirir:
CREATE TABLE kategori (id integer GENERATED ALWAYS AS IDENTITY PRIMARY KEY, ad text);
CREATE TABLE kalem (id integer GENERATED ALWAYS AS IDENTITY, kategori_id integer REFERENCES kategori, ad text);
CREATE VIEW kategori_adlari AS SELECT ad FROM kategori;
DROP TABLE kategori;
DROP TABLE kategori CASCADE;
DROP TABLE IF EXISTS yok_tablo;psql:tb3.sql:20: ERROR: cannot drop table kategori because other objects depend on it
DETAIL: constraint kalem_kategori_id_fkey on table kalem depends on table kategori
view kategori_adlari depends on table kategori
HINT: Use DROP ... CASCADE to drop the dependent objects too.
psql:tb3.sql:21: NOTICE: drop cascades to 2 other objects
DETAIL: drop cascades to constraint kalem_kategori_id_fkey on table kalem
drop cascades to view kategori_adlari
DROP TABLE
psql:tb2.sql:31: NOTICE: table "yok_tablo" does not exist, skipping
DROP TABLE\d kalem ile baktığımızda kalem tablosunun yerinde durduğunu ama yabancı anahtarının kalktığını gördük. Benzer şekilde CREATE TABLE IF NOT EXISTS aynı adda bir tablo varsa yalnızca bildirim verir; belge, var olan tablonun oluşturulmak istenene benzediğinin hiçbir garantisi olmadığını hatırlatır. Yani bu seçenek yapı farklarını yakalamaz.
TRUNCATE: tabloyu hızla boşaltmak

TRUNCATE bir veya birden çok tablonun bütün satırlarını siler. Belgeye göre etkisi koşulsuz bir DELETE ile aynıdır, ama tabloyu taramadığı için daha hızlıdır ve disk alanını sonradan VACUUM beklemeden hemen geri verir. Karşılığında tablo üzerinde ACCESS EXCLUSIVE kilit alır ve eşzamanlı bütün işlemleri bekletir; satır silme tetikleyicilerini (ON DELETE) çalıştırmaz, yalnızca ON TRUNCATE tetikleyicilerini çalıştırır. Başka tablolardan yabancı anahtarla başvurulan bir tablo, o tablolar da aynı komutta boşaltılmadıkça boşaltılamaz:
INSERT INTO kategori (ad) VALUES ('Kırtasiye'), ('Gıda');
INSERT INTO kalem (kategori_id, ad) VALUES (1, 'Silgi'), (2, 'Peynir');
TRUNCATE kategori;
TRUNCATE kategori, kalem RESTART IDENTITY;
INSERT INTO kategori (ad) VALUES ('Temizlik') RETURNING id;psql:tb3.sql:6: ERROR: cannot truncate a table referenced in a foreign key constraint
DETAIL: Table "kalem" references "kategori".
HINT: Truncate table "kalem" at the same time, or use TRUNCATE ... CASCADE.
TRUNCATE TABLE
id
----
1
(1 row)RESTART IDENTITY tablolara ait sequence'leri baştan başlattığı için yeni kayıt yeniden 1 numarasını aldı; varsayılan CONTINUE IDENTITY numaraları olduğu gibi bırakır. CASCADE ise başvuran bütün tabloları otomatik olarak işleme ekler; belge bu seçenekte istemeden veri kaybedebileceğiniz konusunda açıkça uyarır. Bir başka önemli özellik: TRUNCATE transaction güvenlidir, yani çevreleyen transaction geri alınırsa veri geri gelir:
INSERT INTO kategori (ad) VALUES ('Elektronik');
BEGIN;
TRUNCATE kategori CASCADE;
ROLLBACK;
SELECT ad FROM kategori;INSERT 0 1
BEGIN
psql:tb3.sql:15: NOTICE: truncate cascades to table "kalem"
TRUNCATE TABLE
ROLLBACK
ad
------------
Elektronik
(1 row)Belge yine de TRUNCATE'in MVCC açısından güvenli olmadığını belirtir: boşaltmadan önce alınmış anlık görüntüyle çalışan eşzamanlı transaction'lar tabloyu boş görebilir. Eşzamanlı erişim gerekiyorsa DELETE kullanın; satır silmenin ayrıntıları INSERT, UPDATE, DELETE yazısında.
| Komut | Ne siler | Geri alınabilir mi | Not |
|---|---|---|---|
| DELETE FROM t | Satırları (WHERE ile seçerek de) | Evet, transaction içinde | Satır tetikleyicileri çalışır, alan VACUUM ile geri kazanılır |
| TRUNCATE t | Bütün satırları | Evet, transaction içinde | Hızlı, ACCESS EXCLUSIVE kilit, MVCC güvenli değil |
| DROP TABLE t | Tabloyu ve tanımını | Evet, transaction içinde | Bağımlı nesneler için CASCADE gerekir |
Diğer kullanışlı CREATE TABLE biçimleri
LIKE yan tümcesi başka bir tablonun sütun adlarını, tiplerini ve NOT NULL kısıtlarını kopyalar; INCLUDING ALL ile varsayılanlar, identity tanımları (yeni ve ayrı sequence ile), üretim ifadeleri, CHECK kısıtları, indeksler ve PRIMARY KEY, UNIQUE, EXCLUDE kısıtları da gelir; seçenek listesinde yabancı anahtar yoktur. Belgeye göre kopyalanan tablo oluşturulduktan sonra kaynaktan tamamen bağımsızdır. TEMP tablolar oturum sonunda (istenirse transaction sonunda) kendiliğinden silinir ve oturuma özel bir geçici şemada yaşar; autovacuum geçici tablolara erişemediği için büyük geçici tablolarda elle ANALYZE çalıştırmanız önerilir. UNLOGGED tablolar WAL'a yazılmadığı için daha hızlıdır ama çökme veya temiz olmayan kapanış sonrasında otomatik olarak boşaltılır ve standby sunuculara kopyalanmaz.
CREATE TABLE kalem_arsiv (LIKE kalem INCLUDING ALL);
CREATE TEMP TABLE gecici_sepet (urun text, adet integer DEFAULT 1);
\dt List of tables
Schema | Name | Type | Owner
------------+--------------+-------+----------
pg_temp_47 | gecici_sepet | table | postgres
public | Siparis | table | postgres
public | kalem | table | postgres
public | kalem_arsiv | table | postgres
public | urunler | table | postgres
(5 rows)Sık yapılan hatalar
- Satır sırasına güvenmek: SQL satır sırası garanti etmez; sıra gerekiyorsa her sorguda
ORDER BYyazın. - Karışık harfli tırnaklı adlar:
"Siparis"gibi adlar her sorguda tırnak ister; küçük harfli adlar kullanın. - Üretilmiş sütuna değer yazmaya çalışmak: Yalnızca
DEFAULTverilebilir; uygulama ORM'iniz bütün sütunları gönderiyorsa bu sütunları yazma listesinden çıkarın. - Büyük tabloda değişken varsayılanla sütun eklemek:
clock_timestamp()gibi bir varsayılan bütün tabloyu yeniden yazar; önce varsayılansız ekleyipUPDATEile doldurmak ve sonraSET DEFAULTvermek belgede önerilen yoldur. - CASCADE'i düşünmeden kullanmak:
DROP ... CASCADEveTRUNCATE ... CASCADEsizin listelemediğiniz nesneleri de etkiler; önceCASCADE'siz çalıştırıp hata mesajındaki bağımlılık listesini okuyun. - IF NOT EXISTS'i şema göçü sanmak: Tablo varsa komut hiçbir şey yapmaz; farklı yapıdaki eski tabloyu güncellemez.
Sık Sorulan Sorular
Sütunların sırasını değiştirebilir miyim?
ALTER TABLE belgesinde sütun sırasını değiştiren bir biçim yoktur; sütunlar eklendikleri sırada kalır. Sorgularda istediğiniz sırayı seçim listesinde belirtin; fiziksel sıra gerçekten gerekiyorsa yeni bir tablo oluşturup veriyi taşımanız gerekir.
Sanal üretilmiş sütuna indeks koyabilir miyim?
PostgreSQL 18.1 üzerinde denediğimizde hayır: CREATE INDEX ON sanal_dene (b); komutu ERROR: indexes on virtual generated columns are not supported hatası verdi. 18.4 sürüm notları bu mesajın yersiz çıktığı bazı durumları düzeltiyor, ama sanal sütunun kendisini indekslemek desteklenmiyor. İndekslenmesi gereken hesaplanmış değerler için STORED sütun ya da aynı ifade üzerinde bir ifade indeksi kullanın.
TRUNCATE ile DELETE arasında hangisini seçmeliyim?
Bütün tabloyu boşaltacaksanız ve tabloya o sırada başka oturumların erişmesi gerekmiyorsa TRUNCATE daha hızlıdır ve alanı hemen geri verir. Satırların bir kısmını siliyorsanız, satır tetikleyicilerinin çalışması gerekiyorsa veya tablo eşzamanlı kullanılıyorsa DELETE kullanın.
Tablonun tanımını SQL olarak nasıl görürüm?
psql'de \d+ tablo ayrıntılı yapıyı gösterir. Tam CREATE TABLE metnini almak için pg_dump --schema-only -t tablo komutu kullanılabilir; pg_dump yazısında seçenekleri anlatıyoruz.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: PostgreSQL öğrenme rehberi · Primary key, foreign key ve kısıtlar · PostgreSQL veri tipleri · Identity ve sequence · INSERT, UPDATE, DELETE · PostgreSQL 18 yenilikleri