Ответы пользователя по тегу PostgreSQL
  • Как защититься от двойного списания в многопоточном приложении?

    если проверка прошла, то обе выполнятся

    Кто сказал что СУБД позволит выполнить обе транзакции с одними и теми же исходными данными?
    Если обе транзакции начали исполняться параллельно, прочитали одни и те же данные, и пытаются их перезаписать, как СУБД будет себя вести? Позволит ли она вообще отработать обеим транзакциям? Или одна их них подождёт, пока не закончит работу другая? Вопрос гораздо интереснее, чем кажется. И, что самое главное, неглупые люди уже подумали над ним. Очень хорошо подумали.

    В доках постгреса написано ещё лучше.

    Или лучше каждый раз пересчитыапть из истории?

    Запаритесь пересчитывать, это не масштабируется, сложность расчёта будет всё время расти. Если считаете, что можете накосячить с текущим балансом - сделайте возможность его пересчёта согласно истории пополнений/трат. Это называется денормализованными данными. Это один из тех случаев, когда оправдано применение хранимых процедур для актуализации таких данных. Т.е. вместо непосредственной записи одновременно и в историю пополнений/трат и в актуальный баланс прямо из приложения, вы вместо этого вызываете хранимую процедуру, которая атомарно как пишет новую операцию - это ваши основные данные - так и меняет нужным образом ваши денормализованные данные - т.е. ваш баланс. Заодно в этой же хранимке можно дополнительно проверить возможность списания. Это решение не очень хорошо масштабируется, и вообще хранимки это антипаттерн для современных модных-молодёжных распределённых приложений, но судя по вашим вопросам врядли вы отвечаете за разработку сервиса, где таких списаний десятки тысяч в секунду, так что вам хватит.

    Вот на SO ещё предлагают много решений этой классической проблемы, ни одно из которых не является идеальным и лучшим для всех ситуаций.
    Ответ написан
    Комментировать
  • Как получить схему базы Postgres через Select?

    Information Schema (стандартная для всех SQL-баз)
    System Catalogs (специфично для постгреса)
    Ответ написан
    Комментировать
  • Как правильно организовать конкурентный доступ с данным?

    Суть в чем - данные могут редактировать N пользователей, но по сути идеальный вариант - кто первый открыл запись тот и редактирует, остальные могут открыть запись только для просмотра.

    Описываемый вами подход называется пессимистичной блокировкой. Предлагаю поискать по этому термину как такое реализуется.
    Ответ написан
    Комментировать
  • Как получить определенное кол-во строк до необходимой выборки?

    sqlfiddle.com/#!17/12350/11/0
    select val from
    (
        (select val from foo where val < 9 order by val desc limit 5)
        union
        (select val from foo where val >= 9 order by val asc)
    ) results
    order by val asc
    Ответ написан
    Комментировать
  • Как проверить равно ли значение в таблице указанному?

    Поместите сравнение поля с нужной константой в select.
    Ответ написан
    Комментировать
  • Как в posgis найти все записи, где геокоордината содержится в рамках указанного полигона?

    ST_Within вроде как работает только с геометрическим типом. Вероятно, вам нужно скастить gis_centroid к геометрии, добавив к нему '::geometry', только я не уверен, что будет работать индекс. Вам нужно подумать, почему у вас хранится географический тип, если вам нужно работать с ним как с геометрией (а вам нужно именно так, раз у вас карта).
    Ответ написан
    Комментировать
  • Безопасна ли общедоступность схем pg_catalog и information_schema в PostgreSQL?

    Обратимся к документации:
    The catalog pg_authid contains information about database authorization identifiers (roles). A role subsumes the concepts of "users" and "groups". A user is essentially just a role with the rolcanlogin flag set. Any role (with or without rolcanlogin) can have other roles as members; see pg_auth_members.

    Since this catalog contains passwords, it must not be publicly readable. pg_roles is a publicly readable view on pg_authid that blanks out the password field.

    А собственно какой сценарий развития событий вы считаете проблемным? Ну получит некто логин админа, и?
    Ответ написан
  • Как структура баз данных эффективнее: много записей, много таблиц или много баз?

    Безусловно, БД проектируются так, чтобы лучше всего обрабатывать большое количество сущностей в малом количестве "контейнеров" - много записей в небольшом числе таблиц, много документов в небольшом числе коллекций и т.д.

    5 миллионов и даже 100 миллионов записей для нормальной СУБД это вполне адекватная нагрузка (до 1 миллиона - это вообще ни о чём). Как уже заметил Петр , ГОРАЗДО важнее то, какие индексы вы добавите.

    Схемы и таблицы должны добавляться исходя из нужд приложения, например при добавлении новых фич. Базы данных должны создаваться исходы из административных нужд - ограничение доступа, политика резервного копирования и т.д. 5, 10, и даже 50 БД на одном сервере это нормально (если на это есть основания), а вот 500 тысяч - это уже ни в какие ворота.
    Ответ написан
    Комментировать
  • Какие аргументы в пользу использования транзакций в бд?

    И тут выясняется, что ребята совсем нигде(!) не используют транзакций при записи связанных данных. И внешних ключей нигде(!!) в бд не ставят.

    Либо какие-то просветленные, либо дети NoSQL-эры. Скорее всего второе.

    На мои аргументы, что это угрожает целостности данных отвечают, что целостность должна контролироваться на уровне кода самого приложения.

    Да, должна контроллироваться на уровне приложения. Но в большинстве случаев это не повод отказываться от внешний ключей и прочих средств контроля целостности. Да, я видел, что некоторые вендоры НЕ используют ограничения целостности в релизных версиях продуктов, но это скорее исключение, чем правило. И да, самое главное - в большинстве случаев данные живут дольше, чем приложение, с ними работающее. Или - также не редкость - приложений, работающий с одной базой - несколько. Тогда вам рано или поздно захочется дополнительный уровень "доверия", т.е. контроля целостности. Вы должны понимать, что неконсистентные данные в базе - это как правило большой или очень большой гемор, т.к. после появления таких данных в базе очень непросто понять, что они там делают, и что ВАМ теперь с ними делать.
    Ограничения целостности снимают только если они заметно снижают производительность БД, её (производительности) не хватает, других способов быстро поправить ситуацию нет, и у вас на данный момент уже есть хоть какая-то уверенность, что приложение не накосячит в БД.

    А теперь последнее. Целостность данных - не единственное, и даже не главное, для чего нужны и полезны транзакции. Дмитрий Энтелис классно написал про профнепригодность: попросите своих коллег написать биллинг кому-нибудь, выкатить его в продакшн, а потом объяснить начальнику отдела и директору, почему у некоторых клиентов, купивших две услуги по 500, списалось только за одну услугу. Можете рассказать коллегам про уровни изоляции - тут кстати навалом примеров.
    Ответ написан
    2 комментария
  • Как реализовать версионность данных на EntityFramework CodeFirst (метод таблиц-версий, подход TPC)?

    Nipheris
    @Nipheris Куратор тега C#
    Вы уверены, что надо этим мучать EF? Я думаю, версионирование данных это один из кейсов, когда стоит применить триггеры, а не поднимать версионность на уровень объектной БД.
    Ответ написан
    1 комментарий
  • Указание имени БД в строке подключения?

    NpgsqlConnection conn = new NpgsqlConnection("Server=127.0.0.1;Port=5432;User Id=postgres;Password=admin;");
    var databasesTable = conn.GetSchema("Databases", null);
    // проверяем наличие базы данных в таблице databasesTable
    Ответ написан
    Комментировать
  • Практическое использование схем в Postgresql - когда они нужны?

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

    Важно понимать, что различные БД плохо подходят для логического группирования, т.к. разбиение по базам данных нужно скорее для администраторов, а не для приложений. Плюс, в большинстве СУБД, где существует понятие схемы, возможно ставить внешние ключи на таблицы в другой схеме, но нельзя на таблицы в другой БД. Иными словами, отдельные БД удобно создавать тогда, когда вы разделяете данные абсолютно не связанных приложений или сервисов. Например, складского учета и форума поддержки пользователей. С другой стороны, если вы хотите логически разделить таблицы в соответствии с компонентами одного приложения (например, корпоративный портал: 4 таблицы для поддержки авторизации, 10 таблиц для поддержки форума, еще 5 для чата со службой поддержки или отделом продаж) - то именно схемы будут удобным механизмом для этого.

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

    А что будет если несколько юзеров будут на одну public-схему коннектиться?

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

    Вот допустим, у вас есть отдельная схема для таблицы авторизации и аутентификации и отдельная - для корпоративного форума. Сервис авторизации у вас выполнен отдельно от форума (например, авторизация выдаёт токены пользователю, с которыми он потом может зайти на форум). С точки зрения безопаности было бы логичным выдать сервису авторизации и форума различных пользователей в базе - тогда, при взломе форума невозможно будет получить доступ к паролям в базе или изменить права на портале, подправив данные в таблице ролей. Конечно, многие СУБД разрешают ставить права на отдельные таблицы, однако схема в данном случае играет роль контейнера и позволяет проставить единые правила для всех таблиц внутри неё.

    то есть при работе в постгре предпочтительнее вместо отдельных баз делать разные схемы в одной

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

    Вот вам еще хороший пример. У вас есть приложение для ведения бухгалтерии и складского учёта на фирме. При этом сложилось так, что вам нужно хранить на одном сервере данные нескольких разных фирм (например, вы предоставляете готовый сервис под ключ нескольким клиентам). В этой ситуации более чем логично хранить данные разных клиентов в разных БД, а данные бухгалтерского и складского учета - в различных схемах в рамках одной БД конкретного клиента.
    Ответ написан
    2 комментария
  • Как разделять логику запросов в СУБД и PHP?

    Как правильно разделить работу СУБД и PHP?

    Есть очень простой принцип.

    СУБД - это подсистема, которая хранит и извлекает данные, а приложение (на PHP или на чем угодно) - их обрабатывает и модиифицирует, если нужно.
    СУБД архитектурно (и физически) "ближе" к данным. Одна из важнейших задач СУБД - выбрать из всего объема БД только нужные сейчас данные. Именно на уровне СУБД нужно производить максимум фильтраций. У нее есть все нужное для этого - индексы и прочие хитрые структуры данных.

    Однако, чтобы СУБД лучше выполняла свои основные задачи, не стоит нагружать ее лишней вычислительной работой. Все, что не связано с поддержанием целостности и согласованности данных, отдают на уровень приложения - тогда эти вычисления (куда относятся, к примеру, подготовка JSON-ответов или сборка web-страницы по шаблону) можно выполнить логически и физически на других узлах, что влечет за собой очевидные преимущества.

    Поэтому вывод такой: выбирайте как можно меньше записей и столбцов/атрибутов в запросе к БД (т.е., например, никаких * в плановых запросах), и делайте как можно больше работы с ними на уровне приложения (настолько, насколько удается соблюдать требуемые гарантии целостности).
    Под "как можно меньше записей" я имею в виду делать запрос максимально конкретным и узконаправленным, но достаточным для выполнения текущей задачи.
    Ответ написан
    7 комментариев
  • Как база данных производит подсчет строк?

    Да, как реализован COUNT()?

    Зависит от:
    а) того, что будет внутри COUNT
    б) того что будет в WHERE (и будет ли он вообще);
    в) реализации в конкртеной СУБД;

    Пример 1: если вы сделаете COUNT с WHERE по неиндексированному полю, то без сканирования таблицы не обойтись. Кроме того, если поле внутри COUNT() может быть NULL, то СУБД придется выкидывать еще и нуллы, т.к. COUNT их не учитывает.

    Пример 2: если вы сделаете COUNT по первичному ключу без каких-либо фильтров, то СУБД вероятно просто вернет вам количество строк из своих служебных структур, т.к. первичные ключи а) уникальны; б) не могут быть NULL в большинстве сегодняшних СУБД.

    Вывод: SQL это высокоуровневый декларативный язык, который перекладывает принятие алгоритмических решений на планировщик СУБД, что дает очень большой простор для оптимизаций в конкретных реализациях. Лучший рецепт - построить план КОНКРЕТНОГО запроса и увидеть, что потребуется для его выполнения.
    Ответ написан
    Комментировать
  • Как правильно спроектировать базу; консистентность данных?

    > и для каждого из них есть уникальные поля
    А как этими полями будут пользоваться? Группировки/фильтры/агрегация по ним будут?
    Если будут, то тогда действительно 20 таблиц (и это нормально, т.к. тогда и кода для каждого типа пользователя у вас будет достаточно). И паттерны наследования - concrete table, single table, class table.
    Если не будут (т.е. эти поля будут читаться/писаться целиком) - может в JSON поле их?
    Ответ написан
    Комментировать
  • Какая есть хорошая книга c примерами по проектированию базы на SQL с упором на MySQL, PostgreSQL?

    Советую ERWin (коммерческий) и Oracle Data Modeler (бесплатный), а из книг возьмите Дейта для начала.
    Ответ написан
  • C# - PostgreSQL Как работать с GridView?

    Nipheris
    @Nipheris Куратор тега C#
    Вам надо определиться с рядом требований к вашему приложению, в частности - на каком уровне абстракции оно работает с БД. Если на метауровне - т.е. для вашей программы нет ничего кроме набора неких таблиц и вьюх в базе (иными словами у вас чтото вроде стандартного шелла для работы с базой) - то это одна ситуация, и тут вам бы работать с INFORMATION_SCHEMA (чтобы без свитчей) и действительно собирать SQL-запросы самому. Если же у вас стандартные бизнес-задачи (создать запись о клиенте, заказе, ..., сохранить, отредактировать данные), и вы конкретно знаете, что у вас за таблицы и что там хранится, то почитайте про актуальные подходы к работе с данными в базах с использованием ORM, в случае дотнета - Entity Framework и NHibernate.
    Ответ написан
    Комментировать