LINUX.ORG.RU

Сравниваем строки с Юлией Высоцкой

 ,


1

3

Имеется таблица:

create table t (
    "path" text primary key,
    ...
);

Безо всяких там переопределённых collation, дефолтное collation базы – en_US.utf8, connection charset – тоже UTF8.

В таблице этой есть строка со значением path = '/private/auto_test_intern/U3.json' (зуб даю, значение именно такое: 33 байта, все символы – в обычном ASCII).

Делаем:

-- отдаёт 1 строку; length = 33:
select length("path"::bytea), * from t where "path" like '/private/auto_test_intern/U3.json'; 

-- 0 строк:
select * from t where "path" = '/private/auto_test_intern/U3.json';

-- 1 строка:
select * from t where "path" like '/private/auto_test_intern/U3.json' and substr("path", 1, 33) = '/private/auto_test_intern/U3.json';

Вопрос: ЧЗНх во втором запросе?!



Последнее исправление: pr849 (всего исправлений: 4)
Ответ на: комментарий от anonymous

Спасибо, помогло:

reindex table t;

Индекс, разумеется, есть: это ж PK. Мысль такая пробегала, но как-то не задержалась: это ж что должно случиться в транзакционной СУБД, чтобы индекс побился.

pr849
() автор топика
Ответ на: комментарий от pr849

что должно случиться в транзакционной СУБД, чтобы индекс побился.

Ищи причину, для начала проверяй аппаратуру - оперативку, файловую систему, жесткий диск/ssd.
Reset'ы были??

Atlant ★★★★★
()
Ответ на: комментарий от Atlant

Товарищи на созвоне говорят, что не исключено, что косяк возник из-за переноса базы (хз откуда куда, я в ихних инфраструктурных игрищах не участвую). Интересно, возможно ли такое при backup/restore – в процессе restore индексы временно задизаблены, а по завершении restore не построились. (Впрочем, не настолько интересно, чтобы гуглить.)

pr849
() автор топика
Ответ на: комментарий от vbr

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

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

anonymous
()
Ответ на: комментарий от Obezyan

не надо так делать

При такой безапелляционной формулировке - вон из профессии. Текстовые PK - самое обычное дело, в общем случае их применимость зависит от задачи конечно же.

anonymous
()
Ответ на: комментарий от anonymous

При такой безапелляционной формулировке - вон из профессии.

закукарекал анонимус, выгоняйте обезъяна, пробуйте.

Текстовые PK - самое обычное дело

для недоучек

теперь обоссу вас по пунктам:

  1. Безапелляционная формулировка - это «никогда не при каких обстоятельствах не смейте так делать», что отличается от «не надо так делать».

  2. В подавляющем большинстве случаев текстовые PK это результат непродуманной архитектуры БД из-за недостатка знаний и опыта. PK практически во всех базах данных является ссылкой на конкретные данные в таблице поэтому использование строковых ключей большой длины работает медленнее и жрет больше памяти при прочих равных. Причем чем больше база тем хуже работает. Простое правило - чем меньше ключ тем быстрее запрос. Вот полнотекстовые индексы это вполне нормальное явление, а текстовые первичные ключи - нет, если мы говорим не о студенческой лабе на 1000 записей.

Обеткайте, следующий.

Obezyan
()
Ответ на: комментарий от Obezyan

Безапелляционная формулировка - это «никогда не при каких обстоятельствах не смейте так делать», что отличается от «не надо так делать».

Пока ты не написал «как правило» или «в большинстве случаев», никакой разницы нет, котик. На самом деле так даже хуже - если бы ты написал «никогда не при каких обстоятельствах не смейте так делать» все бы сразу поняли что ты дурачок и слушать не стали, а «не надо» же примут за чистую монету и повторять будут.

В подавляющем большинстве случаев

Вот ты и дал заднюю. И почему же ты сразу так не сказал?

это результат непродуманной архитектуры БД из-за недостатка знаний и опыта

Такое исключать, конечно, нельзя, как и любую другую дичь, но я считаю что именно «в большинстве случаев» это таки результат того что данные должны индексироваться по строковому ключу.

PK практически во всех базах данных является ссылкой на конкретные данные в таблице поэтому использование строковых ключей большой длины работает медленнее и жрет больше памяти при прочих равных

Чем что? Для данных которые естественным образом идентифицируются строкой, например домены, альтернативой текстовому ключу будет два индекса - искусственный serial pk и всё тот же текстовый, необходимость в котором никуда не делась, и который в роли вторичного индекса потребляет столько же ресурсов. Два индекса будут гарантировано жрать больше памяти и работать медленнее на запись.

А будет ли быстрее чтения по serial pk зависит, опять же, от кейса. Возможно их вообще не будет, если запросы приходят с тем же естественным ключом. Возможно они будут намного медленнее, потому что у текстовых индексов есть порядок (это значит, например, что сджойнить две таблицы по домену можно дешевейшим index (only) scan, вместо хэширований или сортировок) и локальность (это значит, например, что если хранить инвертированный домен и нам приходит пачка запросов на его поддомены, то чтобы их можно нужно поднять в память всего одну страницу индекса, а не тыкаться по всему диску). Возможно, конечно, и медленнее, если нужно приджойнить таблицу с нелокальными данными - он порядка строк мы ничего не выиграем, а от размера индекса проиграем. Или просто при случайных чтениях.

Причем чем больше база тем хуже работает

Это сбивающее с толку заявление, ибо асимптотика индекса не зависит от размера ключа, только константа меняется. «Чем больше база тем хуже работает» любой btree ключ.

а текстовые первичные ключи - нет, если мы говорим не о студенческой лабе на 1000 записей.

Только студенческие базы на 1000 записей ты и видел, если не встречал юзкейзов для text PK. Просвещайся, дорогой.

anonymous
()
Ответ на: комментарий от vbr

Ну я слишком старый и для меня первичный ключ это однозначность по которому можно прийти к нужной строке.

Не ну можно прийти к … что мол допускается, но это уже на самом деле изврат.

mx__ ★★★★★
()
Ответ на: комментарий от vbr

collation не должен ни на что влиять вроде бы

строго говоря это не так. задаются правила упорядочивания строк содержащих числа, правила сравнения (ci), то есть это влияет и на строки обычных латинских символов и цифр. но в постгресе это в более продвинутых collation.

asdpm
()
Ответ на: комментарий от vbr

я думаю это чушь и ничего не поломалось.

там или продвинутая collation которая зависит от системных библиотек, которые незаметно обновились и оно документировано сломалось (и всех уведомило ворнингами), или, как он говорит сам, «они переносили базу» так

asdpm
()
Ответ на: комментарий от vbr

обновлено

у быдла первичный ключ обязательно должен быть одной колонкой, обязательно должен быть int, обязательно должен автомачески присваиваться монотонно и только вперед и он обязательно должен быть суррогатный. никакой другой не может у быдла

asdpm
()
Последнее исправление: asdpm (всего исправлений: 1)
Ответ на: комментарий от sin_a

Она совершенно точно не красивее строк с SSO в которые влезает sizeof() байт с учётом терминирующего \0. Она более похожа на COW строки с рефкаунтами - кому-то может и зайдёт, в целом же такое себе.

anonymous
()
Ответ на: комментарий от asdpm

А ещё должна быть вторая колонка с UUID, для внешних ссылок, чтобы враг не догадался. Особо продвинутые делают UUIDv7, чтобы он возрастал (типа индексы так компактней), но при этом их в душе гложут сомнения - достаточно ли это безопасно?

vbr ★★★★★
()
Ответ на: комментарий от vbr

о, uuid - это считается модно, продвинуто. замечал, что некоторые пока поступают проще: если хотят сгенерировать случайную hard-to-guess строку (зачем-то, для сесурити), то обязательно считают хеш-функцию. не важно от чего, можно от случайного числа или даже от колонки id (где сами знаете что). главное чтобы хеш. получившаяся шестандцатеричная букво-цифренная строка выглядит очень «шифровано», а вызов hash() в коде дает гораздо больше уверенности в сравнении вызовом randStr()

asdpm
()
Ответ на: комментарий от asdpm

Лучше уж так. Хуже у школьников думающих что они понимают принцип SQL, а потом мало того что это начинает жутко тормозить, так еще и работает не понятно как.

mx__ ★★★★★
()
Ответ на: комментарий от vbr

У топикстартера строка из ASCII, там collation не должен ни на что влиять вроде бы…

это разве что локаль C/POSIX гарантирует, что строки упорядочиваются согласно их байтовому представлению, а у ТС локаль en_US.utf8, а там в 2018 году был невероятный движняк: https://wiki.postgresql.org/wiki/Locale_data_changes.

А вообще это на самом деле какая-то исключительная дурь от PostgreSQL:

  • в том же Oracle индексы создаются без collation: «Because a standard index cannot be used as a source of values sorted in a linguistic order, an explicit sort operation must usually be performed instead of an index range scan. A functional index on the NLSSORT function may be defined to provide values sorted in a linguistic order and reintroduce the index range scan to the execution plan»
  • добиться плана запроса, чтобы записи возвращались в том же порядке, что лежат в индексе, можно за каким-то ну очень редким исключением, например: https://wiki.postgresql.org/wiki/Loose_indexscan
  • надеяться на то, что range scan на текстовых данных будет полезен и хоть как-то адекватно работать - это уже за гранью добра из зла, я себе совершенно не могу представить как нужно задизайнить СУБД, чтобы в условии запроса факт того, что a < b, был хоть сколь полезен

Прагматичный подход здесь такой, что БД нужно создавать всегда с локалью C/POSIX а потребителям отдавать данные с явным указанием сортировки order by (column collate ...), если того требуется.

borisych ★★★★★
()
Ответ на: комментарий от anonymous

При такой безапелляционной формулировке - вон из профессии. Текстовые PK - самое обычное дело, в общем случае их применимость зависит от задачи конечно же.

у анонов и не такое может быть «обычным делом».

anc ★★★★★
()
Ответ на: комментарий от borisych

А вообще это на самом деле какая-то исключительная дурь от PostgreSQL:

в том же Oracle индексы создаются без collation: «Because a standard index cannot be used as a source of values sorted in a linguistic order, an explicit sort operation must usually be performed instead of an index range scan. A functional index on the NLSSORT function may be defined to provide values sorted in a linguistic order and reintroduce the index range scan to the execution plan»

То есть и в оракле и в постгресе можно создавать индексы как с, так и без collation. Но дурь почему-то именно в постгресе. Типичный FUD от фаната проприетарных баз.

надеяться на то, что range scan на текстовых данных будет полезен и хоть как-то адекватно работать - это уже за гранью добра из зла, я себе совершенно не могу представить как нужно задизайнить СУБД, чтобы в условии запроса факт того, что a < b, был хоть сколь полезен

О, вы тоже с опытом работы с СУБД на уровне лабораторных работ, и при этом без фантазии? Неужели так сложно представить таблицу с текстовыми идентификаторами и алфавитной сортировкой? Да хоть телефонную книгу. Так вот когда там становится больше десятка записей, для неё становится нужна пагинация. А пагинацию через offset/limit нормальные люди не делают. Это вам на ваших лабораторных должны были рассказывать, вообще-то. А для этого нужно выбирать по текстовому индексу и > условию. И никак вы по-другому эффективно не сделаете.

anonymous
()
Ответ на: комментарий от asdpm

uuid - это считается модно

Ох жеж.

Вот в контейнеры запихивать ПГ - вот это модно.

А ключи в UUID - это распределенные БД, балансировка и отказоустойчивость.

Toxo2 ★★★★
()
Последнее исправление: Toxo2 (всего исправлений: 1)
Ответ на: комментарий от asdpm

Это звучит гораздо проще и красивее, чем городить огород с разными не пересекающимися счётчиками на разных Мастерах в двусторонней репликации, стоящими физически на разных концах географии.

Toxo2 ★★★★
()
Ответ на: комментарий от Toxo2

Это звучит гораздо проще и красивее, чем городить огород с разными не пересекающимися счётчиками на разных Мастерах в двусторонней репликации, стоящими физически на разных концах географии.

в твоих сообщениях как будто всё смешалось в кучу и мультимастер и шардирование и балансировка и отказоустойчивость и UUID который всё это якобы обеспечивает

asdpm
()
Ответ на: комментарий от Toxo2

А ключи в UUID - это распределенные БД, балансировка и отказоустойчивость.

в первую очередь UUID позволяет взять кусок данных из одной БД в виде insert/upsert и затащить его в другую БД - самый бронебойный вариант, когда нужно подготовить данные на тестовом стенде, а потом влить это все на бой, «альтернативы» выглядят, возможно, и красивее, но на пару порядков сложнее в реализации.

байки про то, что от UUID индексы пухнут - это всего лишь байки, ничего общего не имеющие с действительностью (БД тупит от дизайна, несоответствующего реалиям, а не из-за отсутствия 3NF, рандобных ключей и пр.), в реальности в одну табличку пишет сразу сотня потоков, а расщепление правого блока в этой ситуации - это не гипотетические измышления, а суровая реальность, в Oracle для этого даже reverse index придумали

borisych ★★★★★
()
Ответ на: комментарий от anonymous

анонимус - ты дурак.

Oracle поддерживает кроссплатформенные реплики и DR уже черт знает сколько лет - я разве что застал проблемы LE <-> BE, но и они вроде как в 10g были решены, в «опенсорсе» (PostgreSQL на мой взгляд никакой не опенсорс, а картель) же перетащить базу с одной версии шляпы на другую с минимальным простоем - это что-то из области фантастики (ровно как TC и описал), а все не потому что, где-то существуют какие-то проприетарные решения, а потому что кто-то один раз очень крупно напорол, а после этого еще и не хочет признавать очевидные ошибки (рассмотрение prior art при разработке решения - это обязательный шаг, кто его не делает - тот дебил)

Это вам на ваших лабораторных должны были рассказывать, вообще-то

это кто-то на лабах до сих пор ваяет телефонный справочник с байками про бинарный поиск, логарифмы и прочую дичь, текущие реалии такие, что телефонный справочник как есть заливается в полнотекстовый поиск (нормальный такой полнотекстовый поиск, а не поделку от PostgreSQL), благо данные меняются ну очень редко, и потребитель результат запроса получает практически мгновенно, в отличии от какой-то откровенной SQL-дрочи

borisych ★★★★★
()
Ответ на: комментарий от Obezyan

это результат непродуманной архитектуры БД из-за недостатка знаний и опыта

Или того что база легаси и в неё постепенно добавлялись/удалялись данные, а рефракторинг никто не делал толком и тут костылик подставим, там подпоркой подопрём и так сойдёт.

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от anonymous

это таки результат того что данные должны индексироваться по строковому ключу

Простите, а кому данные что-то должны? Если ты сейчас скажешь что софтине которую кто-то написал так, то я скажу что фигово у вас взаимодействие архитектора баз данных и команды разработки организовано, начальника/тимлида надо нафиг уволить

peregrine ★★★★★
()
Последнее исправление: peregrine (всего исправлений: 1)
Ответ на: комментарий от borisych

Блин, у меня дежавю. Словно читал уже похожий коммент от тебя пару лет назад про

телефонный справочник с байками про бинарный поиск, логарифмы и прочую дичь

peregrine ★★★★★
()