Как моделировать отношения "один ко многим" в DynamoDB

10.03.22

Интеграция - WEB-интеграция

Перевод статьи по DynamoDB, которую можно применить для Yandex Database.

Источник https://www.alexdebrie.com/posts/dynamodb-one-to-many/, Примечание: объединения = соединения = JOIN

Делаю для лучшего понимания применимости связки Yandex Serverless + Yandex Database (Document API, совместим с Amazon DynamoDB) для небольших проектов, которые попадают в бесплатную тарификацию.

 

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

В этом посте мы увидим, как моделировать отношения "один ко многим" в DynamoDB. Отношения "один ко многим" лежат в основе почти всех приложений. В DynamoDB у вас есть несколько различных вариантов представления отношений "один ко многим".

Мы рассмотрим основы отношений "один ко многим", затем рассмотрим пять различных стратегий моделирования отношений "один ко многим" в DynamoDB.

 

Основы отношений "один ко многим"

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

  • Рабочее место: В одном офисе будет работать много сотрудников; у одного менеджера может быть много прямых подчиненных.
  • Электронная коммерция: один клиент может делать несколько заказов с течением времени; один заказ может состоять из нескольких товаров.
  • Учетные записи программного обеспечения как услуги (SaaS): Организация приобретет подписку на SaaS; несколько пользователей будут принадлежать одной организации.

При использовании отношений "один ко многим" возникает одна основная проблема: как мне получить информацию о родительском объекте при извлечении одного или нескольких связанных объектов?

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

В DynamoDB нет объединений. Вместо этого существует ряд стратегий для отношений "один ко многим", и выбранный вами подход будет зависеть от ваших потребностей.

В этом посте мы рассмотрим пять стратегий моделирования отношений "один ко многим" с помощью DynamoDB:

  • Денормализация с использованием сложного атрибута
  • Денормализация путем дублирования данных
  • Составной первичный ключ + действие API запроса
  • Вторичный индекс + действие API запроса
  • Составные ключи сортировки с иерархическими данными

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

 

Денормализация с использованием сложного атрибута

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

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

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

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

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

 

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

DynamoDB работает по-другому. Поскольку соединений нет, нам нужно найти другой способ сбора данных из двух разных типов объектов. В этом примере мы можем добавить атрибут "MailingAddresses" к нашему элементу "Клиент". Этот атрибут представляет собой карту и содержит все адреса для данного клиента:

 

Поскольку "MailingAddresses" содержат несколько значений, запись в таблице больше не является атомарной и, таким образом, нарушает принципы первой нормальной формы.

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

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

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

В нашем примере у нас нет никаких шаблонов доступа, таких как “Поиск клиента по его или ее почтовому адресу”. Все использование атрибута "MailingAddress" будет осуществляться в контексте Клиента, например, для отображения сохраненных адресов на странице оформления заказа. Учитывая эти потребности, для нас вполне нормально сохранить их в сложном атрибуте.

  • Является ли объем данных в сложном атрибуте неограниченным?

Объем одного элемента DynamoDB не может превышать 400 КБ данных. Если объем данных, содержащихся в вашем сложном атрибуте, потенциально неограничен, он не будет хорошо подходить для денормализации и хранения вместе в одном элементе.

В этом примере для нашего приложения разумно установить ограничения на количество почтовых адресов, которые может хранить клиент. Максимум 20 адресов должны удовлетворять почти всем вариантам использования и избегать проблем с ограничением в 400 КБ.

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

Если ответ на любой из вышеприведенных вопросов “Да”, то денормализация со сложным атрибутом не подходит для моделирования этого отношения "один ко многим".

 

Денормализация путем дублирования данных

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

Здесь мы нарушим принципы второй нормальной формы, дублируя данные по нескольким элементам.

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

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

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

Примечание: На самом деле у книги может быть несколько авторов. Для упрощения этого примера мы предполагаем, что у каждой книги ровно один автор.

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

Но у нас нет объединений в DynamoDB. Итак, как мы можем решить эту проблему? Мы можем проигнорировать правила второй нормальной формы и включить биографическую информацию автора в каждый элемент Книги, как показано ниже.

 

 

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

Есть два основных вопроса, которые вы должны задать при рассмотрении этой стратегии:

  • Является ли дублируемая информация неизменяемой?
  • Если данные действительно меняются, то как часто они меняются и сколько элементов содержат дублирующуюся информацию?

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

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

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

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

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

 

Составной первичный ключ + действие API запроса

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

Ключевым понятием в DynamoDB является понятие коллекций элементов. Коллекции элементов - это все элементы таблицы или вторичного индекса, которые используют один и тот же ключ раздела. При использовании действия Query API вы можете извлекать несколько элементов из одной коллекции элементов. Это может включать элементы разных типов, что дает вам поведение, подобное объединению, с гораздо лучшими характеристиками производительности.

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

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

В нашей таблице есть два типа элементов — Организации и Пользователи. Шаблоны для значений PK и SK следующие:

Entity
PK SK
Organizations ORG#<OrgName> METADATA#<OrgName>
Users ORG#<OrgName> User#<UserName>

 

В таблице ниже приведены некоторые примеры элементов:

 

В эту таблицу мы добавили пять элементов — два элемента организации для Microsoft и Amazon и три элемента пользователя для Билла Гейтса, Сатьи Наделлы и Джеффа Безоса.

Красным выделена коллекция элементов для элементов с ключом раздела ORG#MICROSOFT. Обратите внимание, что в этой коллекции есть два разных типа элементов. Зеленым цветом обозначен тип элемента организации в этой коллекции элементов, а синим - тип элемента пользователя в этой коллекции элементов.

Такая конструкция первичного ключа упрощает решение четырех шаблонов доступа:

  • Получить организацию. Используйте вызов GetItem API и название организации, чтобы сделать запрос для элемента с PK ORG#<OrgName> и SK METADATA#<OrgName>.
  • Получить Организацию и всех пользователей внутри Организации. Используйте действие API запроса с выражением ключевого условия PK = ORG#<OrgName>. Это позволит получить Организацию и всех пользователей в ней, поскольку все они имеют один и тот же ключ раздела.
  • Получить только пользователей внутри Организации. Используйте действие API запроса с выражением ключевого условия PK = ORG#<OrgName> AND begins_with(SK, "USER#"). Использование функции begins_with() позволяет нам извлекать только пользователей, не извлекая также объект Организации.
  • Получить конкретного пользователя. Если вы знаете как название организации, так и имя пользователя Пользователя, вы можете использовать вызов GetItem API с PK ORG#<OrgName> и SK USER#<Username> для извлечения элемента User.

Хотя все четыре из этих шаблонов доступа могут быть полезны, второй шаблон доступа — Получение организации и всех пользователей внутри Организации — наиболее интересен для этого обсуждения отношений "один ко многим". Обратите внимание, как мы эмулируем операцию объединения в SQL, размещая родительский объект (Организацию) в той же коллекции элементов, что и связанные объекты (Пользователи). Мы предварительно объединяем наши данные, объединяя их во время записи.

Это довольно распространенный способ моделирования отношений "один ко многим", который будет работать в ряде ситуаций.

 

Вторичный индекс + действие API запроса

Аналогичный шаблон для отношений "один ко многим" заключается в использовании глобального вторичного индекса и API запросов для извлечения многих. Этот шаблон почти такой же, как и предыдущий, но в нем используется вторичный индекс, а не первичные ключи в основной таблице.

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

Для последней ситуации давайте вернемся к нашему последнему примеру. Представьте, что в вашем SaaS-приложении каждый пользователь может создавать и сохранять различные объекты. Если бы это был Google Диск, это мог бы быть документ. Если бы это был Zendesk, это мог бы быть билет. Если бы это была Typeform, это могла бы быть Форма.

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

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

 

Обратите внимание на два новых элемента билета, выделенных красным цветом.

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

Вместо этого давайте попробуем что-нибудь другое. Мы сделаем три вещи:

  • Мы смоделируем наши элементы билетов так, чтобы они находились в отдельной коллекции элементов в главной таблице. Для значений PK и SK мы будем использовать шаблон TICKET#<TicketID>, который позволит осуществлять прямой поиск элемента билета.
  • Создайте глобальный вторичный индекс с именем GSI1, ключами которого являются GSI1PK и GSI1SK.
  • Как для нашего билета, так и для пользовательских элементов добавьте значения для GSI1PK и GSI1SK. Для обоих элементов значением атрибута GSI1PK будет ORG#<OrgName>#USER#<UserName>.

Для элемента "Пользователь" значением GSI1SK будет USER#<UserName>.

Для элемента "Билет" значением GSI1SK будет БИЛЕТ#<TicketID>.

Теперь наша базовая таблица выглядит следующим образом:

 

Обратите внимание, что элементы наших билетов больше не чередуются с их родительскими пользователями в базовой таблице. Кроме того, пользовательские элементы теперь имеют дополнительные атрибуты GSI1PK и GSI1SK, которые будут использоваться для индексации.

Если мы посмотрим на наш вторичный индекс GSI 1, мы увидим следующее:

 

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

Последнее замечание, прежде чем двигаться дальше — обратите внимание, что я структурировал его так, чтобы элемент "Пользователь" был последним элементом в разделе. Это происходит потому, что "Билеты" сортируются по метке времени. Вполне вероятно, что я захочу получить пользователя и самые последние билеты пользователя, а не самые старые билеты. Таким образом, я упорядочиваю его так, чтобы пользователь находился в конце коллекции элементов, и я могу использовать свойство ScanIndexForward=False, чтобы указать, что DynamoDB должен начинаться с конца коллекции элементов и считываться в обратном направлении.

 

Составные ключи сортировки с иерархическими данными

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

Распространенным примером в этой области являются данные, основанные на местоположении. Давайте продолжим нашу тему рабочего места и представим, что вы отслеживаете все местоположения Starbucks по всему миру. Вы хотите иметь возможность фильтровать местоположения Starbucks на произвольных географических уровнях — по стране, штату, городу или почтовому индексу.

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

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

 

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

 

Паттерны таковы:

  • Найдите все местоположения в данной стране. Используйте запрос с выражением ключевого условия PK = <Country>, где страна - это та страна, которую вы хотите.
  • Найдите все местоположения в данной стране и штате. Используйте запрос с выражением условия PK = <Country> AND begins_with(SK, '<State>#').
  • Найдите все местоположения в данной стране, штате и городе. Используйте запрос с выражением условия PK = <Country> AND begins_with(SK, '<State>#<City>').
  • Найдите все местоположения в данной стране, штате, городе и почтовом индексе. Используйте запрос с выражением условия PK = <Country> AND begins_with(SK, '<State>#<City>#<ZipCode>').

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

  • У вас есть много уровней иерархии (> 2), и у вас есть шаблоны доступа для разных уровней внутри иерархии.
  • При поиске на определенном уровне иерархии вам нужны все подпункты этого уровня, а не только элементы этого уровня.

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

Если вам нужно подробное пошаговое руководство по этому примеру, я написал полный пример Starbucks на DynamoDBGuide.com.

 

Вывод

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

Стратегия Примечание Соответствующие примеры
Денормализация с использованием сложного атрибута Хорош, когда вложенные объекты ограничены и к ним нет прямого доступа Почтовые адреса пользователей
Денормализация путем дублирования данных Хорошо, когда дублируемые данные являются неизменяемыми или нечасто изменяющимися Книги и Авторы; Фильмы и Роли
Первичный ключ + API запросов Наиболее распространенный. Подходит для шаблонов множественного доступа к двум типам сущностей. Большинство отношений "один ко многим"
Вторичный индекс + API запросов, аналогичный стратегии первичного ключа. Хорош, когда первичный ключ нужен для чего-то другого. Большинство отношений "один ко многим"
Составной ключ сортировки Подходит для очень иерархичных данных, где вам нужно выполнять поиск на нескольких уровнях иерархии Места расположения Starbucks

 

Учитывайте свои потребности при моделировании отношений "один ко многим" и определите, какая стратегия лучше всего подходит для вашей ситуации.

См. также

Интеграция Альфа Авто 5 / Альфа Авто 6 и AUTOCRM / Инфотек

Сайты и интернет-магазины WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 1С:Управление торговлей 11 Автомобили, автосервисы Россия Управленческий учет Платные (руб)

Интеграционный модуль обмена между конфигурацией Альфа Авто 5 и Альфа Авто 6 и порталом AUTOCRM. Данный модуль универсален. Позволяет работать с несколькими обменами AUTOCRM разных брендов в одной информационной базе в ручном и автоматическом режиме.

36000 руб.

03.08.2020    16014    13    18    

13

Интеграция 1С — Битрикс24. Обмен задачами

Сайты и интернет-магазины Интеграция WEB-интеграция Платформа 1С v8.3 Конфигурации 1cv8 Управленческий учет Платные (руб)

Интеграция 1С и Битрикс24. Разработка имеет двухстороннюю синхронизацию 1С и Битрикс24 задачами. Решение позволяет создавать пользователя в 1С из Битрикс24 и наоборот. Данная разработка технически подходит под все основные конфигурации линейки продуктов 1С:Предприятие 8.3 (8.3.18.1289). При приобретении предоставляется 1 месяц бесплатных обновлений разработки. Доступна демо-версия продукта с подключением Вашего Битрикс24

5040 руб.

04.05.2021    18043    10    15    

14

SALE! 10%

Автоматическая загрузка файлов (например, прайс-листов) из электронной почты, FTP, HTTP, их обработка и выгрузка на FTP (на сайт) и для других целей

Прайсы WEB-интеграция Ценообразование, анализ цен Файловый обмен (TXT, XML, DBF), FTP Автомобили, автосервисы Оптовая торговля, дистрибуция, логистика Управленческий учет Платные (руб)

Программа с заданным интервалом времени (или по ручной команде) скачивает файлы (например, прайс-листы поставщиков) из различных источников: письма электронной почты, FTP или HTTP-адреса, и сохраняет их в каталог упорядоченной структуры. При этом извлекает файлы из архивов, может переименовывать файлы и менять их формат (csv, xls, txt). Можно настроить выгрузку обработанных файлов на сайт (через FTP-подключение). Программа будет полезна компаниям, у которых есть большое количество поставщиков и/или прайс-листы поставщиков обновляются часто (необязательно прайс-листы, файлы могут быть любого назначения). Собранные таким образом актуальные версии прайс-листов можно выгрузить с помощью программы себе на сайт (или на любой FTP-сервер) или выполнить другие необходимые задачи.

28000 25200 руб.

28.05.2015    85224    26    51    

50

Модуль для обмена "1С:Предприятие 8. УАТ. ПРОФ" с FortMonitor

WEB-интеграция 8.3.8 Конфигурации 1cv8 Автомобили, автосервисы Беларусь Украина Россия Казахстан Управленческий учет Платные (руб)

Расширение предназначено для конфигурации "1С:Предприятие 8. Управление Автотранспортом. ПРОФ". Функционал модуля: 1. Заполнение регистров сведений по подсистеме "Мониторинг", а именно: события по мониторингу, координаты по мониторингу, пробег и расход по мониторингу, текущее местоположение ТС по мониторингу 2. Заполнение путевого листа: пробег по мониторингу, время выезда/заезда, табличная часть ГСМ, места стоянок по геозонам. 3. Отчеты по данным загруженным в регистры сведений. 4. Предусмотрена автоматическая загрузка данных в фоновом режиме (условия работы данной загрузке читайте в описании товара) Модуль работает без включенной константы по настройкам мониторинга. Модуль формы предоставляется с открытым кодом, общий модуль защищен. Любой заинтересованный пользователь, имеет возможность скачать демо-версию расширения.

22656 руб.

25.05.2021    12947    32    8    

12

Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС

Обмен с ГосИС WEB-интеграция Платформа 1С v8.3 Управляемые формы 1С:Комплексная автоматизация 1.х 1С:Бухгалтерия 2.0 1С:Управление торговлей 10 1С:Управление производственным предприятием 1С:Управление нашей фирмой 1.6 1С:Бухгалтерия государственного учреждения 1С:Документооборот 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Платные (руб)

Обработка является альтернативой механизму, разработанному фирмой 1С и заполняющему реквизиты контрагента по ИНН или наименованию. Не требуется действующей подписки ИТС. Вызывается как внешняя дополнительная обработка, т.е. используется, непосредственно, из карточки контрагента. Заполнение по ИНН или наименованию реквизитов контрагента по данным сайта ФНС (egrul.nalog.ru) для БП 2.0, БП 3.0, БГУ 1.0, БГУ 2.0, УТ 10.3, УТ 11.x, КА 1.1, КА 2.x, УПП 1.x, ERP 2.x, УНФ 1.5, УНФ 1.6, УНФ 3.0, ДО 2.1

2400 руб.

28.04.2016    89511    163    217    

320
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. starik-2005 3040 10.03.22 10:25 Сейчас в теме
Вот прочитал и показалось мне, что это попытка изобрести квадратноколесый велосипед, которая провалилась...

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

В общем у меня после статьи возникло противоречивое чувство, что авторы этой системы пытаются решить уже давно решенные вопросы путем разбора карбюратора через выхлопную трубу. Надеюсь, что я не прав, но хотелось бы в таком случае пояснений, в чем именно...
2. malikov_pro 1296 10.03.22 11:32 Сейчас в теме
(1) Рядом еще 2 статьи про DynamoDB, возможно из них найдете для себя ответ.

На сколько понял за счет того что одна таблица мы её можем горизонтально масштабировать и без серьезных потерь работать с большими объемами данных. В 2 статьях из 3 упоминание что схема получается сложной и допустить ошибку "на раз два". Оптимизация идет под ограниченный список вариантов выборки/записи данных.

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

Моя цель была понять на сколько подходит для моего проекта использовать Yandex Database, на тех объемах что есть спокойно делаю несколько таблиц и объединяю информацию на уровне сервиса API. Когда изучал SQL упирался в то что связи в виде внешних ключей нужны, но когда покопался в 1С, понял что там их нет (контроль целостности данных на уровне приложения, а не СУБД), с этими знаниями буду делать свой новый сервис.
3. starik-2005 3040 10.03.22 11:40 Сейчас в теме
(2)
Рядом еще 2 статьи про
Да, там определенным образом описывается миграция RDB в noSQL. Мне, лично. кажется пока, что здесь вообще разный подход к данным, который позволяет сценарии RDB использовать в noSQL, при этом они, конечно, нуждаются в серьезной переработке и адаптации. И да, если чего-то в итоге не хватит, то придется перерисовывать абсолютно все с достаточно высокой степенью вероятности (какие общие слова, да?))))

В принципе, в 1С тоже ведь объекты, которые не без извратов пытаются засунуть в связанные таблицы реляционной базы данных. И к этим извратам вроде как все привыкли, по крайней мере это позволяет собирать оперативную информацию из срезов уже давно и всем известным способом, организовывать при этом многосессионный доступ к данным, сохраняя пресловутый принципе ACID, поступаясь при этом производительностью, и существенно. И вроде как кажется, что ORM создан для noSQL - объектных баз данных, но привычка - вторая натура, поэтому сложно выйти за рамки шаблонов нормализации, хотя она для noSQL тоже не является пустым звуком (банально исходя из бритвы Окамма, которая в пределе отражает ШЕСТУЮ нормальную форму)...
4. malikov_pro 1296 10.03.22 11:43 Сейчас в теме
(1) В дополнении о способах решения задачи.
Леруа Мерлен используют для агрегации остатков Kafka, которая подрезается по последним в рамках уникальности ключей, а отдачу делают из Tarantool. Если абстрагироваться то это СУБД с последовательным доступом к данным.

Так же интересно сделать прототип регистра накопления на ClickHouse, который за счет сочетаний движков может на лету считать остатки в материализованное представление, у них подход что одна таблица под транзакции а остальное в присоединяемых словарях (на сколько понял концепт).
5. starik-2005 3040 10.03.22 11:54 Сейчас в теме
(4)
прототип регистра накопления на ClickHouse
Мне кажется, что вообще все также, как на обычной БД - таблица с движениями и итогами, хотя итоги можно вычислять каждый раз агрегируя обороты - для этого вроде как есть куча разных модификаторов для столбцов таблицы. С REDIS это упражнение было бы интереснее.
6. malikov_pro 1296 10.03.22 11:58 Сейчас в теме
(3) "да, если чего-то в итоге не хватит, то придется перерисовывать абсолютно все с достаточно высокой степенью вероятности (какие общие слова, да?))))" - перегнули немного.
Но и в RDB сначала данные распределили, с учетом того что доменная модель может уточняться и таблицы могут "пухнуть" (спр. Номенклатура например), а далее начинаются проблемы с производительностью которые решают за счет материализованных вью, доп индексов, частичной денормализации, создания промежуточных таблиц с перегрузкой индекса (index overloading) в виде ключей аналитики.
Авторы статей достаточно четко артикулируют что при проектировании таблицы учитывается не только набор данных но и варианты работы с ним, при изменении требований ETL инструменты в помощь.

На мой взгляд это хорошо сочетается с контейнеризацией доменной модели.

Близко по смыслу в контексте Docker контейнеризации описано у "ArchDays 2019 • Как списать технический долг • Максим Смирнов" (https://www.youtube.com/watch?v=HRRv82L75wU). Не надо тащить техдолг, напишите на актуальнй платформе и перетащите нужные данные.
7. starik-2005 3040 10.03.22 12:01 Сейчас в теме
(6)
Не надо тащить техдолг, напишите на актуальнй платформе и перетащите нужные данные.
Это, кстати, хороший подход, если нужно получить некий результат одной конкретной функции, которая сейчас работает неудовлетворительно. Целиком продукт так не перенести, но, слава богам, в последнее время - и Вы, как я понял, это уловили - приложение пишется, как совокупность сервисов (провайдеров) и очередей данных, а дальше некий ETL в витрину и средства визуализации витрины для BI.

НО: докер ради докера - тоже странно. Его преимущество в том, что среда мигрирует вместе с контейнером. Нет отличий среды - нет проблем совместимости. Но в итоге докер тащат и в совершенно другие применения, где он нафиг не нужен. Ну и разработку начинают вести без оглядки на совместимость, что тоже не айс...
8. malikov_pro 1296 10.03.22 12:04 Сейчас в теме
(5) Вы правы, 2 таблицы, первая на ReplacingMergeTree, вторая зависима от первой и на AggregatingMergeTree (еще разбираться с SummingMergeTree и выбирать оптимум).

"С REDIS это упражнение было бы интереснее." - это всего лишь кеш (in memory), для которого нужна основа из которой при падении он может подтянуть данные (в чем различия с тарантулом не разбирался)
9. starik-2005 3040 10.03.22 12:09 Сейчас в теме
(8)
для которого нужна основа из которой при падении он может подтянуть данны
ДокерREDIS сохраняет данные в запакованный дамп. Да, делает это не онлайн, но тут компромисс между высокой доступностью и высокой надежностью. В последнее время народ все чаще предлагает засунуть и MS SQL (и PostgreSQL) целиком в память, что как бы уже "ну ваще-е-е-е....", поэтому тот же REDIS, как дампирующийся кешер, из-за очень высокой скорости доступа вполне может выступать в качестве хранилища и оперативных остатков тоже. Ну и блокировки на нем очень просто делать через функции обмена (типа SET X,1, в результате которой возвращается уже установленное значение, и если оно уже 1, то блокировка была установлена ранее).
10. malikov_pro 1296 10.03.22 12:23 Сейчас в теме
(9) Давайте не смешивать зоны ответственности. Docker это контейнер для запуска, рассчитывать на то что "сохраняет данные в запакованный дамп" некорректно, например, мне нужно поднять + 5 инстансов с Redis, они либо берут данные "от соседей" либо от агрегированного источника данных, можно его сделать и на PG в виде отдельной таблицы, на сколько удобно её заполнять и масштабировать отдельный вопрос.

"Все чаще предлагает засунуть целиком в память" причина понятна, "у нас есть X, у нас есть опыт работы с ним, давайте его и так провернем", но X писался под свой класс задач. Сейчас с облачными решениями стоимость обслуживания технологии относительно невысока и больше вопрос в подборе оптимальных инструментов. Важные для меня мысли у Максима Смирнова "Сервисы живут дольше чем технологии которые их реализуют -> IT -это услуга".
11. starik-2005 3040 10.03.22 12:30 Сейчас в теме
(10)
Docker
Да, я исправился. Зарапортовался. Имелось ввиду "REDIS".

Слово "оптимальные" нифига не значит сейчас. Вообще.
Оставьте свое сообщение