PostgreSQL varchar ile character varying farkı

PostgreSQL "varchar (n)" ve "char (n)" notasyonları, sırasıyla "character varying (n)" ve "character (n)" için takma adlardır. Uzunluk belirteci olmayan character, character (1) ile eşdeğerdir. Character varying uzunluk belirteci olmadan kullanıldığında, tür herhangi bir uzunluktaki dizeyi kabul eder. 

Öyleyse varchar mı , yoksa character varying mi kullanmalıyız ?

Character varying veri tipi temelde varchar veri tipiyle aynıdır fakat SQL ANSI standartına uygunluk sağlamak amacıyla PostgreSQL'de kullanımına izin verilir. Hatta yeni PostgreSQL sürümlerinde yarattığınız sütun veri tipi varchar olsa da otomatik olarak character varying'e dönüştürülmektedir.

CREATE TABLE "TMP"."SpecialCustomer"
(
    "ID" bigint NOT NULL DEFAULT nextval('"TMP"."SpecialCustomer_ID_seq"'::regclass),
    "Name" varchar(100) NOT NULL COLLATE pg_catalog."default",
    "SurName" character varying(100) NOT NULL COLLATE pg_catalog."default",
    "Description" character varying COLLATE pg_catalog."default"
)

Örnek kodda gösterildiği gibi SpecialCustomer tablosunu yarattığınızda Name ve SurName alanları eğer yeni bir PostgreSQL sürümü kullanıyorsanız otomatik olarak  character varying(100) 'e çevrilecektir. Bunun bir sebebi SQL ANSI standartında 100 karakterlik bir alana 5 karakter veri girdiğinizde geriye kalan 95 karakter için boşluk benzeri bir işaret konularak veri tabanında eşit yer kaplaması sağlanmasıdır. Character varying tipinde bu tip bir eşitlemeye gerek duyulmamaktadır.

Diğer veritabanlarından farklı olarak varchar, character varying, text veri tipi uzunluk belirteci kullanılmadığı durumlarda 1GB veri saklayabilmektedir. Yani aralarında SQL ANSI standartı ile gelen sona boşluk karakteri atılması dışında fark bulunmamaktadır. Diğer veri tabanlarında Oracle varchar2 4000 karakter, SQL varchar 8000 karakter, MySQL varchar 65535 karakter ile sınırlandırılmıştır. Oracle CLOB, SQL TEXT, MySQL LONGTEXT alanları PostgreSQL TEXT tipiyle benzer olup kapladıkları alan itibariyle örtüşmezler.

Character varying veri tipi tablodaki "Description" sütununda belirtildiği gibi herhangi bir uzunluk belirteci ile sınırlanmazsa 1GB veri aldığını belirtmiştik. Ek olarak 126 bayt üstündeki veriler sıkıştırmaya tabi tutulacağından uzun bir metin dizesi genellikle standart bir metin dizesinden çok daha fazla yer kaplamaz. Yani "character varying (n)" gibi kısıtlayıcı notasyonları eğer mecburiyetiniz yoksa kullanmanıza gerek olmayıp, kullanmadığınızda performans ve disk kaybı yaşamazsınız. TCKimlikNo, sicil veya bir takım özel anahtarları kaydederken Constraints kısıt sorunlarını aşmak ve veri bütünlüğünü sağlamak için (n) notasyonunu zaten kullanmak durumundayız.

Son bir örnekle pekiştirmek istersek "A&B LTD.ŞTİ." şeklinde ki verimiz character varying için 12 karakter 13 bayt iken , varchar veri tipinde yine 12 karakter 13 bayt yer kaplayacaktır. Fakat Varchar(12) notasyonu UTF8 yerine UTF16 kullanan bir çok veri tabanında 12 bayt anlamı taşıdığından ilgili veriyi kolona kaydetmek mümkün olmayacaktır. Bunun yerine 12 karakteri garanti eden ve ihtiyacınız olan 13 Bayt alanı otomatik olarak sağlayan "Character Varying (12)" veri tipini kullanmak daha az sorun yaşanmasını sağlayacaktır.

 

Sonuç olarak aralarında ciddi performans farkı olmamasına rağmen PostgreSQL SQL ANSI uyumlu olan "varchar" tipi sona eklenen boşluk karakteri nedeniyle daha fazla disk alanı işgal etmekte ve uzunluğu kontrol ederken fazladan bir kaç C dili döngüsü kullanmaktadır. Zaten PostgreSQL güncel sürümlerde yaratılan tablolardaki varchar sütunları otomatik olarak "character varying" 'e cast etmektedir. Bu durumda adamların bir bildikleri olmalı savıyla :) mümkün olduğunca character varying kullanmaya gayret edilmelidir.

Kaynak: https://www.postgresql.org/docs/12/datatype-character.html