Postgresql: разработка расширений (функций) на языке с

Q2: way to measure page size

PostgreSQL предоставляет ряд , вы можете использовать. Я собрал самые интересные из них в этом запросе и добавил некоторые .

Это продемонстрирует, что различные методы измерения «размера строки» могут привести к очень различным результатам. Все зависит от того, что вы хотите точно измерить.

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

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

Общая статистика count строк добавляется в конце с нетрадиционным SQL-foo, чтобы получить все в одном запросе. Вы можете перенести его в функцию plpgsql для повторного использования, указать имя таблицы в качестве параметра и использовать .

Результат:

что | bytes /ct | bytes_pretty | bytes_per_row
----------------------------------- + ---------- + --- ----------- + ---------------
 core_relation_size | 44138496 | 42 МБ | 91
 visibility_map | 0 | 0 байт | 0
 free_space_map | 32768 | 32 kB | 0
 table_size_incl_toast | 44179456 | 42 МБ | 91
 indexes_size | 33128448 | 32 МБ | 68
 total_size_incl_toast_and_indexes | 77307904 | 74 МБ | 159
 live_rows_in_text_representation | 29987360 | 29 МБ | 62
 ------------------------------ | | |
 row_count | 483424 | |
 live_tuples | 483424 | |
 dead_tuples | 2677 | |

Дополнительный модуль pgstattuple обеспечивает более полезные функции.

Обновление для Postgres 9.3 +

Мы могли бы использовать новую форму в стр. 9.4, используя несколько параметров для параллельной работы с массивами.
Но используя и выражение , это может быть упрощены далее. Кроме того, некоторые другие улучшения:

Тот же результат.

JSONB

Наконец, в Postgres 9.4 мы получили настоящую и правильную поддержку JSON в виде JSONB. B означает “лучше” (Better). JSONB — это бинарное представление данных в формата JSON. Это означает, что данные сжимается и более эффективны для хранения, чем обычный текст. Кроме того, под капотом у него механизм, подобный Hstore. Технически, когда-то при разработке, был почти реализованный тип Hstore2 и отдельный тип JSON и впоследствии они были объединены в JSONB в том виде, как он есть сейчас.

Тип JSONB представляет в значительной степени то, что вы могли бы ожидать от типа данных JSON. Он позволяет реализовывать вложенные структуры, использовать основные типы данных, а также имеет ряд встроенных функций для работы с ним. Лучшей частью такой схожести с Hstore является индексация. Создание индекса GIN на колонке JSONB создаст индекс по каждому ключу и значению в пределах этого документа JSON. Возможность индексации и вложенность данных внутри документа означают, что JSONB превосходит Hstore в большинстве случаев.

Хотя все еще остаётся небольшой вопрос о том, в каких случаях следует использовать исключительно JSONB. Допустим, вы создаете базу данных документов и из всех вариантов выбираете Postgres. С пакетом, наподобие MassiveJS это может быть довольно удобным.

Наиболее распространенные примеры использования:

  1. Отслеживание событий данных, добавляя изменяющийся payload события.
  2. Хранение игровых данные достаточно распространено, особенно там, где у вас есть одиночная игра и изменяющаяся схема данных на основе состояния пользователя.
  3. Инструменты, которые объединяют несколько источников данных, пример здесь может быть инструментом, который интегрирует несколько баз данных клиентов к Salesforce, к Zendesk или к чему-то еще. Сочетание схем делает это более болезненной процедурой, чем она должна быть.

Давайте рассмотрим, другой пример работы с JSONB. Скрипт создает таблицу и вставляет некоторые данные для примера:

История

PostgreSQL создана на основе некоммерческой СУБД Postgres, разработанной как open-source проект в Калифорнийском университете в Беркли. К разработке Postgres, начавшейся в 1986 году, имел непосредственное отношение Майкл Стоунбрейкер, руководитель более раннего проекта Ingres, на тот момент уже приобретённого компанией Computer Associates. Название расшифровывалось как «Post Ingres», и при создании Postgres были применены многие уже ранее сделанные наработки.

Стоунбрейкер и его студенты разрабатывали новую СУБД в течение восьми лет с по 1994 год. За этот период в синтаксис были введены процедуры, правила, пользовательские типы и другие компоненты. В 1995 году разработка снова разделилась: Стоунбрейкер использовал полученный опыт в создании коммерческой СУБД Illustra, продвигаемой его собственной одноимённой компанией (приобретённой впоследствии компанией Informix), а его студенты разработали новую версию Postgres — Postgres95, в которой язык запросов POSTQUEL — наследие Ingres — был заменен на SQL.

Разработка Postgres95 была выведена за пределы университета и передана команде энтузиастов. Новая СУБД получила имя, под которым она известна и развивается в текущий момент — PostgreSQL.

Производные продукты

Лицензия PostgreSQL позволяет на его основе создавать различные, в том числе коммерческие, форки. Их известно несколько десятков .

На базе PostgreSQL компанией EnterpriseDB были разработаны другие варианты этой СУБД, являющиеся платными для коммерческого использования — Postgres Plus (состоит целиком только из продуктов с открытыми исходными кодами; плата требуется только при необходимости приобретения коммерческой поддержки продукта) и Postgres Plus Advanced Server (расширение PostgreSQL специальными возможностями для обеспечения совместимости с Oracle Database). В комплекте поставки данных продуктов содержится набор ПО для разработчиков и администраторов баз данных:

  • Postgres Studio — аналог phpPgAdmin;
  • Postgres Plus Debugger — отладчик для кода на PL/pgSQL, интегрированный с предыдущим пакетом;
  • Migration Studio — инструмент для автоматического преобразования баз данных из MySQL/Oracle в PostgreSQL

В 2015 году российская компания Postgres Professional выпустила свою СУБД Postgres Pro, также являющуюся коммерческим форком PostgreSQL. В варианте Standard СУБД распространяется с исходными кодами и представляет собой версию PostgreSQL с патчами для ядра PostgreSQL, которые уже приняты сообществом и внесены в основную ветку, а также с собственными расширениями, разработанными компанией Postgres Professional. Таким образом обеспечивается доступ к полезной функциональности и обновлениям почти за год до выхода нового релиза PostgreSQL. В варианте Enterprise данная СУБД содержит бо́льшее количество дополнений, предназначенных для работы с большими, высокопроизводительными базами данных с повышенными требованиями к надежности.

Числовые типы данных

Ниже приведены числовые типы данных в PostgreSQL:

Синтаксис типов данных Пояснение
bit(size) Битовая строка фиксированной длины, где size — длина строки битов.
varbit(size) bit varying(size) Битовая строка переменной длины, где size — длина строки битов.
smallint Эквивалентно int2.   2-байтовое целое число со знаком.
int Эквивалентно int4. 4-байтовое целое число со знаком.
integer Эквивалентно int4. 4-байтовое целое число со знаком.
bigint Большое целочисленное значение, эквивалентное int8. 8-байтовое целое число со знаком.
smallserial Небольшое целочисленное значение с автоинкрементом, эквивалентное serial2. 2-байтовое целое число со знаком, автоинкрементное.
serial Автоинкрементное целочисленное значение, эквивалентное serial4. 4-байтовое целое число со знаком, автоинкрементное.
bigserial Большое автоинкрементное целочисленное значение, эквивалентное serial8. 8-байтовое целое число со знаком, автоинкрементное.
numeric(m,d) Где m — это общее количество цифр, а d — это число после десятичной дроби.
double precision 8 байт, двойная точность, число с плавающей точкой
real 4-байтовое число одинарной точности с плавающей точкой
money Стоимость валюты.
bool Логический логический тип данных — true или false
boolean Логический логический тип данных — true или false

Изменение таблиц

Последнее обновление: 19.03.2018

Нередко возникает изменить уже имеющуюся таблицу, в частности, добавить или удалить столбцы, изменить тип столбцов и т.д..
То есть потребуется изменить определение таблицы. Для этого применяется выражение ALTER TABLE,
которое имеет следующий формальный синтаксис:

ALTER TABLE название_таблицы
{ ADD название_столбца тип_данных_столбца  | 
  DROP COLUMN название_столбца |
  ALTER COLUMN название_столбца параметры_столбца |
  ADD  определение_ограничения |
  DROP  имя_ограничения}

Рассмотрим некоторые возможности по изменению таблицы.

Добавление нового столбца

Добавим в таблицу Customers новый столбец Phone:

ALTER TABLE Customers
ADD Phone CHARACTER VARYING(20) NULL;

Здесь столбец Phone имеет тип , и для него определен атрибут , то есть
столбец допускает отсутствие значения. Но что если нам надо добавить столбец, который не должен принимать значения NULL? Если в таблице есть
данные, то следующая команда не будет выполнена:

ALTER TABLE Customers
ADD Address CHARACTER VARYING(30) NOT NULL;

Поэтому в данном случае решение состоит в установке значения по умолчанию через атрибут :

ALTER TABLE Customers
ADD Address CHARACTER VARYING(30) NOT NULL DEFAULT 'Неизвестно';

Удалим столбец Address из таблицы Customers:

ALTER TABLE Customers
DROP COLUMN Address;

Изменение типа столбца

Для изменения типа применяется ключевое слово TYPE. Изменим в таблице Customers тип данных у столбца FirstName на (он же ):

ALTER TABLE Customers
ALTER COLUMN FirstName TYPE VARCHAR(50);

Изменение ограничений столбца

Для добавления ограничения применяется оператор SET, после которого указывается ограничение.
Например, установим для столбца FirstName ограничение :

ALTER TABLE Customers 
ALTER COLUMN FirstName 
SET NOT NULL;

Для удаления ограничения применяется оператор DROP, после которого указывается ограничение.
Например, удалим выше установленное ограничение:

ALTER TABLE Customers 
ALTER COLUMN FirstName 
DROP NOT NULL;

Изменение ограничений таблицы

Добавление ограничения CHECK:

ALTER TABLE Customers
ADD CHECK (Age > 0);

Добавление первичного ключа :

ALTER TABLE Customers 
ADD PRIMARY KEY (cust_id);
ALTER TABLE Customers
ADD UNIQUE (Email);

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

Также мы можем явным образом назначить ограничению при добавлении имя с помощью оператора CONSTRAINT.

ALTER TABLE Customers
ADD CONSTRAINT phone_unique UNIQUE (Phone);

В данном случае ограничение будет называться «phone_unique».

Чтобы удалить ограничение, надо знать его имя, которое указывается после выражения . Например, удалим выше добавленное ограничение:

ALTER TABLE Customers
DROP CONSTRAINT phone_unique;

Переименование столбца и таблицы

Переименуем столбец Address в City:

ALTER TABLE Customers
RENAME COLUMN Address TO City;

Переименуем таблицу Customers в Users:

ALTER TABLE Customers
RENAME TO Users;

НазадВперед

Что такое функции в SQL?

Функции – это объекты базы данных, которые используются для автоматизации и упрощения расчетов. Функции пишутся уже с использованием настоящего языка программирования в PostgreSQL — это PL/pgSQL.

PL/pgSQL – язык программирования, который используется в СУБД PostgreSQL для написания функций, триггеров и других управляющих конструкций.

Сразу скажу, что писать функции без базовых знаний SQL практически невозможно, поэтому советую ознакомиться с основами SQL, например, Вам помогут вот эти статьи:

  • Основы языка запросов SQL
  • Строковые функции SQL
  • Как добавить новый столбец в таблицу на SQL?

Теперь давайте поговорим о том, для чего нам нужны эти самые функции. Как и в любом языке программирования есть «встроенные» функции, а также есть возможность писать свои «пользовательские» функции и PL/pgSQL не исключение, если быть точнее, то SQL не исключение, так как PL/pgSQL является расширением языка SQL.

В функциях мы можем легко прописывать условия, как и в других языках программирования, в функцию можно передавать параметры и соответственно она может нам возвращать результат, после выполнения действий с входящими параметрами. Одной из главных особенностей функций является то, что при обращении к базе данных из приложения все действия происходят на сервере, что гораздо быстрей, т.е. эффективней. Если не использовать вызов функций из приложения, то обращаться к базе данных придется несколько раз, что в свою очередь замедляет работу.

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

В функциях в СУБД PostgreSQL можно использовать все операторы SQL такие как: INSERT, DELETE, UPDATE и другие. И Вы теперь представьте, что можно прописать в функции!? а потом просто  вызвать ее одной строкой.

Прочие возможности

  • Соблюдение принципов ACID
  • Соответствие стандартам ANSI SQL-92, SQL-99, SQL:2003, SQL:2011
  • Поддержка запросов с , , , , и подзапросов
  • Последовательности
  • Контроль целостности
  • Репликация
  • Общие табличные выражения и рекурсивные запросы
  • Аналитические функции
  • Поддержка Юникода (UTF-8)
  • Поддержка регулярных выражений в стиле Perl
  • Встроенная поддержка SSL, SELinux и Kerberos
  • Протокол разделяемых блокировок
  • Подгружаемые расширения, поддерживающие SHA1, MD5, XML
  • Расширения для написания сложных выборок, отчётов и т. д. (API открыт)
  • Средства для генерации совместимого с другими системами SQL-кода и импорта из других систем
  • Автономные блоки на доступных языках, а не только SQL

Write mappings

There are three rules that determine the PostgreSQL type sent for a parameter:

  1. If the parameter’s is set, it is used.
  2. If the parameter’s is set, it is used.
  3. If the parameter’s is set, it is used.
  4. If none of the above is set, the backend type will be inferred from the CLR value type.

Note that for and , the attribute determines whether to use or .

NpgsqlDbType DbType PostgreSQL type Accepted .NET types
Boolean Boolean boolean bool
Smallint Int16 smallint short
Integer Int32 integer int
Bigint Int64 bigint long
Real Single real float
Double Double double precision double
Numeric Decimal, VarNumeric numeric decimal
Money Currency money decimal
Text String, StringFixedLength, AnsiString, AnsiStringFixedLength text string, char[], char
Varchar character varying string, char[], char
Char character string, char[], char
Citext citext string, char[], char
Json json string, char[], char
Jsonb jsonb string, char[], char
Xml xml string, char[], char
Point point NpgsqlPoint
LSeg lseg NpgsqlLSeg
Path path NpgsqlPath
Polygon polygon NpgsqlPolygon
Line line NpgsqlLine
Circle circle NpgsqlCircle
Box box NpgsqlBox
Bit bit BitArray, bool, string
Varbit bit varying BitArray, bool, string
Hstore hstore IDictionary<string, string>
Uuid uuid Guid
Cidr cidr ValueTuple<IPAddress, int>, IPAddress, NpgsqlInet
Inet inet ValueTuple<IPAddress, int>, IPAddress, NpgsqlInet
MacAddr macaddr PhysicalAddress
TsQuery tsquery NpgsqlTsQuery
TsVector tsvector NpgsqlTsVector
Date Date date DateTime, NpgsqlDate
Interval interval TimeSpan, NpgsqlTimeSpan
Timestamp DateTime, DateTime2 timestamp without time zone DateTime, NpgsqlDateTime
TimestampTz DateTimeOffset timestamp with time zone DateTime, DateTimeOffset, NpgsqlDateTime
Time Time time without time zone TimeSpan
TimeTz time with time zone DateTimeOffset, DateTime, TimeSpan
Bytea Binary bytea byte[], ArraySegment<byte>
Oid oid uint
Xid xid uint
Cid cid uint
Oidvector oidvector uint[]
Name name string, char[], char
InternalChar (internal) char byte
Composite composite types T
Range | (other NpgsqlDbType) range types NpgsqlRange<TElement>
Enum enum types TEnum
Array | (other NpgsqlDbType) array types Array, IList<T>, IList

Notes when using Range and Array, bitwise-or NpgsqlDbType.Range or NpgsqlDbType.Array with the child type. For example, to construct the NpgsqlDbType for a , write . To construct the NpgsqlDbType for an , write .

For information about enums, see the Enums and Composites page.

.NET type Auto-inferred PostgreSQL type
bool boolean
byte smallint
sbyte smallint
short smallint
int integer
long bigint
float real
double double precision
decimal numeric
string text
char[] text
char text
NpgsqlPoint point
NpgsqlLSeg lseg
NpgsqlPath path
NpgsqlPolygon polygon
NpgsqlLine line
NpgsqlCircle circle
NpgsqlBox box
BitArray bit varying
Guid uuid
IPAddress inet
NpgsqlInet inet
PhysicalAddress macaddr
NpgsqlTsQuery tsquery
NpgsqlTsVector tsvector
NpgsqlDate date
NpgsqlDateTime timestamp without time zone
DateTime timestamp without time zone
DateTimeOffset timestamp with time zone
TimeSpan interval
byte[] bytea
Custom composite type composite types
NpgsqlRange<TElement> range types
Enum types enum types
Array types array types

Типы данных

Пнд, 12/15/2008 — 10:33 — admin

Документация по PostgreSQL 8.4devel
Prev Fast Backward Fast Forward Next

Chapter 8. Типы данных

Table of Contents
8.1. Числовые типы
8.1.1.
8.1.2.
8.1.3.
8.1.4.
8.2. Денежные типы
8.3. Символьные типы
8.4. Двоичные типы данных
8.5. Типы дата/времени
8.5.1.
8.5.2.
8.5.3.
8.5.4.
8.5.5.
8.5.6.
8.6. Логический тип
8.7. Перечисления
8.7.1.
8.7.2.
8.7.3.
8.7.4.
8.8. Геометрические типы
8.8.1.
8.8.2.
8.8.3.
8.8.4.
8.8.5.
8.8.6.
8.9. Типы сетевых адресов
8.9.1.
8.9.2.
8.9.3.
8.9.4.
8.10. Типы битовых строк
8.11. Типы текстового поиска
8.11.1.
8.11.2.
8.12. Тип UUID
8.13. Тип XML
8.13.1.
8.13.2.
8.13.3.
8.14. Arrays
8.14.1.
8.14.2.
8.14.3.
8.14.4.
8.14.5.
8.14.6.
8.15. Composite Types
8.15.1.
8.15.2.
8.15.3.
8.15.4.
8.15.5.
8.16. Типы идентификаторов объектов
8.17. Псевдо-типы

PostgreSQL имеет богатый список доступных
пользователю встроенных типов. Кроме того, с помощью команды
CREATE TYPE
пользователи могут добавлять новые типы данных.

показывает все встроенные типы данных
общего назначения. Большая часть альтернативных имён, перечисленных
в колонке «Псевдонимы», используется в
PostgreSQL по историческим причинам.
Кроме того, доступны, но не указаны, некоторые типы данных,
которые используются для внутренних нужд PostgreSQL
или которые устарели.

Table 8-1. Типы данных

Имя Псевдонимы Описание
bigint int8 знаковое восьмибайтное целое число
bigserial serial8 восьмибайтное целое число с автоинкрементом
bit [ (n) ]   битовая строка с фиксированной длиной
bit varying [ (n) ] varbit битовая строка с переменной длиной
boolean bool логическое значение (истина/ложь)
box   четырёхугольник на плоскости
bytea   двоичные данные («массив байт»)
character varying [ (n) ] varchar [ (n) ] строка с переменной длиной
character [ (n) ] char [ (n) ] строка с фиксированной длиной
cidr   адрес сети IPv4 или IPv6
circle   круг на плоскости
date   календарная дата (год, месяц, день)
double precision float8 число с плавающей точкой двойной точности
inet   адрес узла IPv4 или IPv6
integer int, int4 знаковое четырёхбайтовое целое
interval [ fields ] [ (p) ]   промежуток времени
line   бесконечная линия на плоскости
lseg   сегмент линии на плоскости
macaddr   MAC адрес
money   денежное значение (в валюте)
numeric [ (p,
s) ]
decimal [ (p,
s) ]
точное числовое значение с выбраной точностью
path   геометрический путь на плоскости (ломаная)
point   геометрическая точка на плоскости
polygon   закрытый геометрический путь на плоскости (полигон)
real float4 число с плавающей точкой одинарной точности
smallint int2 знаковое двухбайтное целое число
serial serial4 четырёхбайтное целое число с автоинкрементом
text   строка символов перменной длины
time [ (p) ]   время дня
time [ (p) ] with time zone timetz время дня, включая часовой пояс
timestamp [ (p) ]   дата и время
timestamp [ (p) ] with time zone timestamptz дата и время, включая часовой пояс
tsquery   запрос текстового поиска
tsvector   документ текстового поиска
txid_snapshot   снимок ID транзакции уровня пользователя
uuid   универсальный уникальный идентификатор
xml   данные XML

Каждый тип данных имеет внешнее представление, определяемое
с помощью функций ввода и вывода. Многие из встроенных типов
имеют понятные внешние форматы. Однако, некоторые типы являются
либо уникальными в PostgreSQL, такие
как геометрические, либо имеют несколько возможных форматов, такие
как типы даты и времени. Некоторые функции ввода и вывода являются
неинвертирумыми. К ним относятся такие функции, результат вывода
которых может привести к потере точности по сравнению с введённым
первоначальным значением.

Prev Home Next
WITH Queries Up Числовые типы

fetched

Поддержка стандартов, возможности, особенности

PostgreSQL базируется на языке SQL и поддерживает многие из возможностей стандарта SQL:2011.

В PostgreSQL версии 9.5.3 есть следующие параметры:

Максимальный размер базы данных Нет ограничений
Максимальный размер таблицы 32 Тбайт
Максимальный размер записи 1,6 Тбайт
Максимальный размер поля 1 Гбайт
Максимум записей в таблице Нет ограничений
Максимум полей в записи 250—1600, в зависимости от типов полей
Максимум индексов в таблице Нет ограничений

Сильными сторонами PostgreSQL считаются:

  • высокопроизводительные и надёжные механизмы транзакций и репликации;
  • расширяемая система встроенных языков программирования: в стандартной поставке поддерживаются PL/pgSQL, PL/Perl, PL/Python и PL/Tcl; дополнительно можно использовать PL/Java, PL/PHP, PL/Py, PL/R, PL/Ruby, PL/Scheme, PL/sh и PL/V8, а также имеется поддержка загрузки C-совместимых модулей;
  • наследование;
  • легкая расширяемость.

Read mappings

The following shows the mappings used when reading values.

  • The default type is returned when using , and similar methods.
  • You can read as other types by calling .
  • Provider-specific types are returne by .
PostgreSQL type Default .NET type Provider-specific type Other .NET types
boolean bool
smallint short byte, sbyte, int, long, float, double, decimal
integer int byte, short, long, float, double, decimal
bigint long long, byte, short, int, float, double, decimal
real float double
double precision double
numeric decimal byte, short, int, long, float, double
money decimal
text string char[]
character varying string char[]
character string char[]
citext string char[]
json string char[]
jsonb string char[]
xml string char[]
point NpgsqlPoint
lseg NpgsqlLSeg
path NpgsqlPath
polygon NpgsqlPolygon
line NpgsqlLine
circle NpgsqlCircle
box NpgsqlBox
bit(1) bool BitArray
bit(n) BitArray
bit varying BitArray
hstore Dictionary<string, string>
uuid Guid
cidr (IPAddress, int) NpgsqlInet
inet IPAddress (IPAddress, int) NpgsqlInet
macaddr PhysicalAddress
tsquery NpgsqlTsQuery
tsvector NpgsqlTsVector
date DateTime NpgsqlDate
interval TimeSpan NpgsqlTimeSpan
timestamp without time zone DateTime (Unspecified) NpgsqlDateTime
timestamp with time zone DateTime (Local) NpgsqlDateTime DateTimeOffset
time without time zone TimeSpan
time with time zone DateTimeOffset DateTimeOffset, DateTime, TimeSpan
bytea byte[]
oid uint
xid uint
cid uint
oidvector uint[]
name string char[]
(internal) char char byte, short, int, long
geometry (PostGIS) PostgisGeometry
record object[]
composite types T
range subtypes NpgsqlRange<TElement>
enum types TEnum
array types Array (of element type)

The Default .NET type column specifies the data type will return.

will return a value of a data type specified in the Provider-specific type column, or the Default .NET type if there is no specialization.

Finally, the third column specifies other CLR types which Npgsql supports for the PostgreSQL data type. These can be retrieved by calling , , etc. or via .

Как отобразить список всех баз данных сервера PostgreSQL?

Для данной цели существует специальная команда в консольной утилите:

# \l

Результат:

                                           List of databases
    Name     |   Owner    | Encoding  |   Collate   |    Ctype    |     Access privileges     
-------------+------------+-----------+-------------+-------------+---------------------------
 sampledb    | sampleuser | UTF8      | uk_UA.UTF-8 | uk_UA.UTF-8 | =Tc/sampleuser
             |            |           |             |             | sampleuser=CTc/sampleuser
 postgres    | postgres   | UTF8      | uk_UA.UTF-8 | uk_UA.UTF-8 | 
 template0   | postgres   | UTF8      | uk_UA.UTF-8 | uk_UA.UTF-8 | =c/postgres
             |            |           |             |             | postgres=CTc/postgres
 template1   | postgres   | UTF8      | uk_UA.UTF-8 | uk_UA.UTF-8 | postgres=CTc/postgres
             |            |           |             |             | pgsql=CTc/postgres
             |            |           |             |             | =c/postgres

Работа с данными и полями таблиц

Удаление одинаковых строк

Если так получилось, что в таблице нет первичного ключа (primary key), то наверняка среди записей найдутся дубликаты. Если для такой таблицы, особенно большого размера, необходимо поставить ограничения (constraint) для проверки целостности, то удалим следующие элементы:

  • дублирующиеся строки,
  • ситуации, когда одна или более колонок дублируются (если эти колонки предполагается использовать в качестве первичного ключа).

Рассмотрим таблицу с данными покупателей, где задублирована целая строка (вторая по счёту).

Удалить все дубликаты поможет следующий запрос:

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

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

Вебинар «Производительность 1С на PostgreSQL в Яндекс.Облаке»

27 августа в 12:00 в 12:00, онлайн, беcплатно

tproger.ru

События и курсы на tproger.ru

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

Если допустимо удаление дубликатов без сохранения всех данных, выполним такой запрос:

Если данные важны, то сначала нужно найти записи с дубликатами:

Перед удалением такие записи можно перенести во временную таблицу или заменить в них значение на другое.

Общая форма запроса на удаление описанных выше записей выглядит следующим образом:

Безопасное изменение типа поля

Может возникнуть вопрос о включении в этот список такой задачи. Ведь в PostgreSQL изменить тип поля очень просто с помощью команды . Давайте для примера снова рассмотрим таблицу с покупателями.

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

Но в результате выполнения получим ошибку:

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

В результате всё прошло без ошибок:

Обратите внимание, что при использовании кроме конкретного выражения возможно использование функций, других полей и операторов. Например, преобразуем поле обратно в , но с преобразованием формата данных:

Например, преобразуем поле обратно в , но с преобразованием формата данных:

В результате таблица примет следующий вид:

Поиск «потерянных» значений

Будьте внимательны при использовании последовательностей (sequence) в качестве первичного ключа (primary key): при назначении некоторые элементы последовательности случайно пропускаются, в результате работы с таблицей некоторые записи удаляются. Такие значения можно использовать снова, но найти их в больших таблицах сложно.

Рассмотрим два варианта поиска.

Первый способ
Выполним следующий запрос, чтобы найти начало интервала с «потерянным» значением:

В результате получим значения: , и .

Если нужно найти не только первое вхождение, а все пропущенные значения, используем следующий (ресурсоёмкий!) запрос:

В результате видим следующий результат: , и .

Второй способ
Получаем имя последовательности, связанной с :

И находим все пропущенные идентификаторы:

Подсчёт количества строк в таблице

Количество строк вычисляется стандартной функцией , но её можно использовать с дополнительными условиями.

Общее количество строк в таблице:

Количество строк при условии, что указанное поле не содержит :

Количество уникальных строк по указанному полю:

Использование транзакций

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

Начнём транзакцию с помощью команды .

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

А чтобы применить — команду .

Просмотр и завершение исполняемых запросов

Для того, чтобы получить информацию о запросах, выполним следующую команду:

Для того, чтобы остановить конкретный запрос, выполним следующую команду, с указанием id процесса (pid):

Для того, чтобы прекратить работу запроса, выполним:

Создание функций на PL/pgSQL

Теперь давайте будем учиться писать эти самые функции. И для начала ниже представлен общий синтаксис написания функции в PL/pgSQL:

   
   CREATE OR REPLACE FUNCTION название функции (типы передаваемых данных через запятую)
        RETURNS тип возвращаемого значения AS
   $BODY$
        DECLARE
        Объявление переменных
        BEGIN
        Тело программы
        RETURN возвращаемый результат;
        END;
   $BODY$
        LANGUAGE язык, на котором написана функция (например, SQL или plpgsql) VOLATILE

Тип возвращаемого значения может быть разный, например, numeric, integer, text или, например void это тип, который не возвращает значение, а функция просто отрабатывает (например, добавляет новые строки).

Сейчас давайте напишем простенькую функцию, пока без использования plpgsql. Допустим, у нас есть две таблицы с одинаковой строуктурой: test и test1:

Test1

id name flag znach
1 mike 1 10
2 peter 15

и Test2

id number name2 tarif
1 111 mike1 2
2 222 peter1 3

Например, мы часто используем в запросах объединение этих двух таблиц, для того чтобы подтянуть к таблице test1, столбец number из таблицы test2. Для упрощения всего этого давайте напишем простенькую функцию:

   
   CREATE OR REPLACE FUNCTION "work".test_number(numeric)
           RETURNS numeric AS
   $BODY$
           SELECT "number" 
           FROM "work"."test2" 
           WHERE id = $1;
   $BODY$
        LANGUAGE 'sql' VOLATILE

Где,

  • test_number — название функции;
  • numeric — тип входящего параметра (он у нас один, но их может быть много);
  • SELECT «number» FROM «work».»test2″ WHERE id = $1 – запрос, т.е. тело функции. $1 передаваемый параметр;
  • LANGUAGE ‘sql’ VOLATILE – язык, на котором написана функция.

Теперь давайте вызовем нашу функцию в запросе, это проще простого:

  
   SELECT *, "work".test_number(id) AS Number 
   FROM import.test1

где, «work».test_number(id) – это и есть вызов нашей функции. Мы передали ему параметр id, т.е. целую колонку, результат будет таким:

id name flag znach number
1 mike 1 10 111
2 peter 15 222

Если нужно кого-то конкретного подтянуть, можно написать вот так, т.е. передать параметр 1 (id=1).

  
  SELECT *, "work".test_number(1) AS Number
  FROM import.test1
  WHERE id = 1

Таким образом, у нас выведется одна строка:

id name flag znach number
1 mike 1 10 111

Здесь мы с Вами обошлись без всякого рода объединений, согласитесь так намного проще, запрос короче и выполняется быстрей.

Теперь попробуем написать функцию уже с использованием языка PL/pgSQL. Допустим, мы хотим знать, кто в нашей таблице соответствует тому или иному признаку. Например, кто из наших сотрудников работает. Определять будем по признаку flag (1 – работает; 0 – не работает). При этом нам не удобно вспоминать чему соответствует этот признак, например 1, поэтому давайте напишем функцию, чтобы видеть надпись, напротив того или иного сотрудника. Пишем функцию:

   
   CREATE OR REPLACE FUNCTION "work".test_if(numeric)
           RETURNS text AS
   $BODY$
        DECLARE
           val ALIAS FOR $1;
           val1 integer;
           val2 text;
        BEGIN 
        
        val1 :=1;
        
        IF val1 = val THEN
           val2 := 'Он работает'; 
        ELSE 
           val2 := 'Не работает';
        END IF;
        
        RETURN val2;
        
        END;
   $BODY$
        LANGUAGE 'plpgsql' VOLATILE

Здесь мы уже используем объявление переменных, условие и возвращение значения.

Вызываем функцию.

   
   SELECT *, "work".test_if(flag) AS Status
   FROM import.test1

Получаем результат:

id name flag znach status
1 mike 1 10 Он работает
2 peter 15 Не работает

Как Вы уже, наверное, поняли, что возможности функций практически не ограничены, на языке PL/pgSQL можно написать очень серьезные функции, с трудными расчетами и так далее. В данной заметке мы с Вами рассмотрели только основы написания, а дальше зависит только о Вас. Удачи!

Нравится1Не нравится

Заключение

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

Резюмируя, алгоритм выбора решения:

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector