Я должен использовать встроенный varchar (макс.) столбец или сохранить его в отдельной таблице?

Вы можете перебирать ключи словаря так:

for item in dic:
    if searchterm in item:
        print('do something')
16
задан Vadim Kotov 24 October 2017 в 10:48
поделиться

6 ответов

Оставить в строке. SQL Server уже хранит столбцы MAX в отдельной «единице распределения» с SQL 2005. См. Организация таблиц и индексов . По сути, это то же самое, что и сохранение столбца MAX в его собственной таблице, но без каких-либо недостатков явного выполнения этого.

Наличие явной таблицы на самом деле было бы как медленнее (из-за ограничения внешнего ключа), так и занимало бы больше места (из-за дублирования DetaiID). Не говоря уже о том, что для этого требуется больше кода, а ошибки появляются при ... написании кода.

альтернативный текст http://i.msdn.microsoft.com/ms189051.3be61595-d405-4b30-9794-755842d7db7e(en -us, SQL.100) .gif

Обновление

Чтобы проверить фактическое расположение данных, простой тест может показать это: После изменения параметров таблицы и вставки новой строки (sp_tableoption не влияет на существующие строки), типы MAX были вытеснены в их собственное хранилище:

sp_tableoption 'a' , 'large value types out of row', '1';
insert into a (v_a, nv_a, m_a, nm_a, t, nt)
values ('2v_a', N'2nv_a', '2m_a', N'2nm_a', '2t', N'2nt');    
dbcc page(2,1, 200, 3);

Обратите внимание, что столбцы m_a и nm_a теперь являются текстовыми указателями в блоке распределения больших объектов:

Slot 1 Column 2 Offset 0x19 Length 4 Length (physical) 4
v_a = 2v_a                           
Slot 1 Column 3 Offset 0x1d Length 10 Length (physical) 10
nv_a = 2nv_a                         
m_a = [Textpointer] Slot 1 Column 4 Offset 0x27 Length 16 Length (physical) 16
TextTimeStamp = 131268608            RowId = (1:182:2)                    
nm_a = [Textpointer] Slot 1 Column 5 Offset 0x37 Length 16 Length (physical) 16
TextTimeStamp = 131334144            RowId = (1:182:3)                    
t = [Textpointer] Slot 1 Column 6 Offset 0x47 Length 16 Length (physical) 16
TextTimeStamp = 131399680            RowId = (1:182:4)                    
nt = [Textpointer] Slot 1 Column 7 Offset 0x57 Length 16 Length (physical) 16
TextTimeStamp = 131465216            RowId = (1:182:5)                    

Для простоты завершения мы также можем принудительно вывести одно из полей, отличных от max, из строки:

update a set v_a = replicate('X', 8000);
dbcc page(2,1, 200, 3);

Обратите внимание, как столбец v_a хранится в хранилище Row-Overflow:

Slot 0 Column 1 Offset 0x4 Length 4 Length (physical) 4
v_a = [BLOB Inline Root] Slot 0 Column 2 Offset 0x19 Length 24 Length (physical) 24
Level = 0                            Unused = 99                          UpdateSeq = 1
TimeStamp = 1098383360               
Link 0
Size = 8000                          RowId = (1:176:0) 

Итак, как другие уже прокомментировали, MAX по умолчанию типы хранятся встроенными, если они подходят. Для многих проектов DW это было бы неприемлемо, потому что типичные загрузки DW должны сканировать или, по крайней мере, сканировать диапазон, поэтому следует использовать sp_tableoption ..., 'большие типы значений вне строки', '1' . Обратите внимание, что это не влияет на существующие строки, в моем тесте даже при перестроении индекса , поэтому эту опцию нужно включить заранее.

Для большинства загрузок типа OLTP, хотя тот факт, что типы MAX хранятся встроенными, если это возможно, на самом деле является преимуществом, поскольку шаблон доступа OLTP заключается в поиске, а ширина строки мало влияет на него.

Тем не менее, в отношении исходный вопрос: отдельная таблица не нужна. Включение опции больших значений типов вне строки дает тот же результат при бесплатной разработке / тестировании.

28
ответ дан 30 November 2019 в 16:24
поделиться

Наличие обнуляемого столбца стоит 2 байта на каждые 16 из них. Если это единственный (или 17-й, или 33-й и т. Д.) Обнуляемый столбец в таблице, он будет стоить вам 2 байта на строку, иначе ничего.

0
ответ дан 30 November 2019 в 16:24
поделиться

Парадоксально, но если ваши данные обычно меньше 8000 символов, я бы сохранил их в отдельной таблице, а если данные больше 8000 символов, я бы сохранил их в той же таблице.

Это происходит потому, что SQL Server сохраняет данные на странице, если он позволяет строке размещаться на одной странице, но когда данные становятся больше, он перемещает их, как и тип данных TEXT, и оставляет только указатель в строке. Таким образом, для группы из 3000 строк символов вы помещаете меньше строк на страницу, что действительно неэффективно, но для группы из 12000 строк символов данные находятся вне строки, поэтому на самом деле это более эффективно.

Сказав это, это, как правило, у вас есть широкий диапазон длин, поэтому я бы перенес его в отдельный стол. Это дает вам гибкость для перемещения этой таблицы в другую группу файлов и т. Д.

Обратите внимание, что вы также можете указать его, чтобы принудительно выводить данные из строки , используя параметр sp_tableoption . varchar (max) в основном аналогичен типу данных TEXT, при этом по умолчанию используются данные в строке (для varchar (max)) вместо данных вне строки (для TEXT).

10
ответ дан 30 November 2019 в 16:24
поделиться

Вы должны структурировать свои данные в наиболее логичную структуру и позволить SQL Server выполнять оптимизацию в отношении того, как физически хранить данные.

Если вы обнаружите, посредством анализа производительности, что ваша структура является проблемой производительности, рассмотрите возможность внесения изменений в вашу структуру или в настройки хранилища.

2
ответ дан 30 November 2019 в 16:24
поделиться

Оставить в строке. Весь смысл varchar в том, что он занимает 0 байтов, если он пуст, 4 байта для "Hello" и т. Д.

0
ответ дан 30 November 2019 в 16:24
поделиться

Я бы нормализовал это, создав таблицу деталей. Я предполагаю, что некоторые записи в журнале будут иметь одинаковые детали? Поэтому, если вы нормализуете его, вы будете хранить только FK id INTEGER вместо текста для каждого вхождения, если вы сохранили текст в таблице сведений. Если у вас есть причины для отмены нормального режима, сделайте это, но, судя по вашему вопросу, я не понимаю, что это так.

0
ответ дан 30 November 2019 в 16:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: