Długość pola takstowego

Długość pola takstowego
AN
  • Rejestracja: dni
  • Ostatnio: dni
0

Pytanie dotyczy głównie MS SQL w wersji 2008R2 i nowszych, ale też będę wdzięczny za info odnośnie innych baz SQL (np. MySQL, Postgress, Firebird).

Czy to prawda, że pole tekstowe lub bajtowe (varchar lub varbinary) zajmuje tyle bajtów, ile zajmuje zapisana w informacja? Jeżeli tak, to czy jeżeli są dwie takie same tabele, jedna z polami tekstowymi varchar(100), a druga z polami varchar(8000), ale obie tabele będą mieć takie same dane (wartości pól tekstowych do 100 znaków), to czy obie tabele będą zajmować tyle samo miejsca i operacje na nich tak samo wydajne? Jeżeli tak, to w jakich sytuacjach wielkość pola tekstowego ma istotne znaczenie (poza przewidywaną długością wartości pól). Wydaje mi się, że systemy baz danych, w których pole zajmuje zawsze tyle, ile maksymalna długość (np. DBase) odeszły w niepamięć.

Ponadto, w MSSQL zauważyłem, że jak się spróbuje wstawić wartość tekstową dłuższa niż długość pola, to jest komunikat "String or binary data would be truncated" i polecenie insert lub update nie wykonuje się i zrywa transakcję. Treść komunikatu można przetłumaczyć jako "Napis lub ciąg bajtowy będą obcięte", co można rozumieć, że serwer może wstawić wartość do tabeli, tylko, że będzie ona obcięta do długości pola. Jeżeli w danej aplikacji jest akceptowane obcinanie napisów przy wstawianiu do tabeli, to jak przestawić serwer, żeby on przepuszczał próbę wstawienia dłuższego napisu i wstawił obcięty bez obcinania go w aplikacji lub komplikowania danego polecenia insert lub update (na przykład w sytuacji, gdy polecenia SQL wytwarza ORM, a programista nie ma na nie wpływu)?

mariano901229
  • Rejestracja: dni
  • Ostatnio: dni
  • Postów: 597
0
andrzejlisek napisał(a):

Pytanie dotyczy głównie MS SQL w wersji 2008R2 i nowszych, ale też będę wdzięczny za info odnośnie innych baz SQL (np. MySQL, Postgress, Firebird).

Czy to prawda, że pole tekstowe lub bajtowe (varchar lub varbinary) zajmuje tyle bajtów, ile zajmuje zapisana w informacja? Jeżeli tak, to czy jeżeli są dwie takie same tabele, jedna z polami tekstowymi varchar(100), a druga z polami varchar(8000), ale obie tabele będą mieć takie same dane (wartości pól tekstowych do 100 znaków), to czy obie tabele będą zajmować tyle samo miejsca i operacje na nich tak samo wydajne? Jeżeli tak, to w jakich sytuacjach wielkość pola tekstowego ma istotne znaczenie (poza przewidywaną długością wartości pól). Wydaje mi się, że systemy baz danych, w których pole zajmuje zawsze tyle, ile maksymalna długość (np. DBase) odeszły w niepamięć.

Jeżeli masz dwie kolumny varchar(50) i varchar(max) i wpiszesz tu i tu słowo "Konstantynopol". To oznaczałoby, że ta druga kolumna alokuje 2^31-3 znaki w pamięci na przechowywanie tego pola (tyle bodajże można wprowadzić w kolumnie z atrybutem varchar(max)) ? To by było trochę bez sensu. Tutaj ciekawe porównanie wydajności:
http://rusanu.com/2010/03/22/performance-comparison-of-varcharmax-vs-varcharn/

andrzejlisek napisał(a):

Ponadto, w MSSQL zauważyłem, że jak się spróbuje wstawić wartość tekstową dłuższa niż długość pola, to jest komunikat "String or binary data would be truncated" i polecenie insert lub update nie wykonuje się i zrywa transakcję. Treść komunikatu można przetłumaczyć jako "Napis lub ciąg bajtowy będą obcięte", co można rozumieć, że serwer może wstawić wartość do tabeli, tylko, że będzie ona obcięta do długości pola. Jeżeli w danej aplikacji jest akceptowane obcinanie napisów przy wstawianiu do tabeli, to jak przestawić serwer, żeby on przepuszczał próbę wstawienia dłuższego napisu i wstawił obcięty bez obcinania go w aplikacji lub komplikowania danego polecenia insert lub update (na przykład w sytuacji, gdy polecenia SQL wytwarza ORM, a programista nie ma na nie wpływu)?

Trigger, walidacja po stronie aplikacji albo https://www.mssqltips.com/sqlservertip/2857/silent-truncation-of-sql-server-data-inserts/ .

Vardamir
  • Rejestracja: dni
  • Ostatnio: dni
  • Lokalizacja: Wrocław
0
mariano901229 napisał(a):

Jeżeli masz dwie kolumny varchar(50) i varchar(max) i wpiszesz tu i tu słowo "Konstantynopol". To oznaczałoby, że ta druga kolumna alokuje 2^31-3 znaki w pamięci na przechowywanie tego pola (tyle bodajże można wprowadzić w kolumnie z atrybutem varchar(max)) ? To by było trochę bez sensu. Tutaj ciekawe porównanie wydajności:
http://rusanu.com/2010/03/22/performance-comparison-of-varcharmax-vs-varcharn/

Varchar(Max) to zupełnie co innego niż Varchar(8000) bo może przechowywać znacznie dłuższe ciągi znaków (do 2GB). Poza tym wcale nie jest alokowane tyle "znaków" w pamięci ale tyle ile zajmuje ten ciąg znaków + dwa bajty na określenie jego długości.

Jeśli chodzi o komunikat "String or binary data would be truncated" to jest to zgłoszone jako Bug i ma zostać poprawione.
https://connect.microsoft.com/SQLServer/feedback/details/339410/please-fix-the-string-or-binary-data-would-be-truncated-message-to-give-the-column-name

EDIT.

andrzejlisek napisał(a):

Czy to prawda, że pole tekstowe lub bajtowe (varchar lub varbinary) zajmuje tyle bajtów, ile zajmuje zapisana w informacja? Jeżeli tak, to czy jeżeli są dwie takie same tabele, jedna z polami tekstowymi varchar(100), a druga z polami varchar(8000), ale obie tabele będą mieć takie same dane (wartości pól tekstowych do 100 znaków), to czy obie tabele będą zajmować tyle samo miejsca i operacje na nich tak samo wydajne?

Zatem odpowiedź na twoje pytanie brzmi: tak (plus dwa bajty na zapis długości), tak i tak (pod warunkiem, że jest to jedyna kolumna w tabeli). Operacje będą wykonywane tak samo o ile dane rzeczywiście nie będą przekraczać 100 znaków.

AN
  • Rejestracja: dni
  • Ostatnio: dni
0

Rozumiem, że trzeba rozróżniać varchar(max) i varchar(n), bo różnią się sposobem działania i wydajnością na korzyść varchar(n).

Czyli potwierdzacie, że jeżeli dla pól tekstowych będę robić varchar(8000) zamiast mniejszych liczb, ale nie varchar(max), to nie będzie to miało wpływu na objętość bazy danych i wydajność aplikacji przy tych samych założeniach odnoście samych danych?

Jeżeli tak, to w takim razie nie rozumiem, po co między innymi Microsoft i Oracle przewidzieli definiowanie wielkości długości pola tekstowego, skoro wystarczy tak naprawdę tylko dwa typy bez wartości, które można nazwać na przykład "varcharsmall" i "varcharlarge", które w przypadku MSSQL byłyby odpowiednikami varchar(8000) i varchar(max).

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.