Что такое некоторые Ваши самые полезные стандарты базы данных?

В Swift версии 3.0.2 используйте это:

masteryProgress.transform = masteryProgress.transform.scaledBy(x: 1, y: 5)
44
задан 12 revs, 5 users 100% 15 September 2012 в 02:35
поделиться

30 ответов

Вы можете использовать $ ("# elementID"). Height () == 0, так как вы знаете, что он будет либо вверх, либо вниз. Это может быть быстрее, чем выполнение .is (": visible"), но я не тестировал этот факт.

sqlservercentral.com/articles/T-SQL/66097/)[1279 visibleDocumentation

  • Создание диаграмм базы данных
  • Создание словаря данных

Нормализация и ссылочная целостность

  • Максимальное использование первичных ключей одного столбца насколько возможно. При необходимости используйте уникальные ограничения.
  • Ссылочная целостность будет всегда соблюдаться
  • Избегать ON DELETE CASCADE
  • OLTP должен быть не менее 4NF
  • Оценивать каждое отношение «один ко многим» как потенциальное «многие ко многим» отношение
  • Первичные ключи, не созданные пользователем
  • Построение Модели на основе вставки вместо обновлений
  • От PK до FK должно быть то же имя (Employee.EmployeeId - это то же поле, что и EmployeeSalary.EmployeeId)
  • За исключением случаев, когда есть двойное соединение (Person.PersonId присоединяется к PersonRelation.PersonId_Parent и PersonRelation.PersonId_Child)

Обслуживание: периодически запускать сценарии, чтобы найти

  • Схема без таблицы
  • Потерянные записи
  • Таблицы без первичных ключей
  • Таблицы без индексов
  • Недетерминированный UDF
  • Резервное копирование, резервное копирование, резервное копирование

Будьте хороши

  • Будьте последовательны
  • Исправьте ошибки сейчас
  • Прочтите стиль программирования SQL Джо Селко (ISBN 978-0120887972)
11
ответ дан 26 November 2019 в 21:44
поделиться
  • Назовите хранимые процедуры с одинаковым таргетингом и тем же префиксом, например, если у вас есть 3 хранимые процедуры для Person. Таким образом, все для человека сгруппировано в одном месте, и вы можете легко их найти, не просматривая все свои процедуры, чтобы найти их.
    • PersonUpdate
    • PersonDelete
    • PersonCreate
  • Сделайте то же самое для таблиц, когда у вас есть группы таблиц со связанными данными. Например:
    • InvoiceHeaders
    • InvoiceLines
    • InvoiceLineDetails
  • Если у вас есть возможность схем в вашей базе данных, используйте их. Намного приятнее увидеть:
    • Invoice.Header
    • Invoice.Line.Items
    • Invoice.Line.Item.Details
    • Person.Update
    • Person.Delete
    • Person.Create
  • Не использовать триггеры если нет другого разумного подхода для достижения этой цели.
  • Присваивайте именам полей значащий префикс, чтобы вы могли без объяснения причин определить, из какой таблицы они берутся. Таким образом, когда вы видите ссылку на имя поля, вы можете легко определить, из какой таблицы оно происходит.
  • Используйте согласованные типы данных для полей, содержащих похожие данные, т.е. не храните номер телефона как числовой в одной таблице и varchar в другой. На самом деле, не храните его как числовое, если я наткнусь на отрицательный номер телефона, я разозлюсь.
  • Не используйте пробелы или другие непонятные символы в именах таблиц / полей. Они должны быть полностью буквенно-цифровыми - или, если бы у меня были мои барабаны, полностью алфавитный, за исключением подчеркивания. В настоящее время я работаю над унаследованной системой, в которой имена таблиц и полей содержат пробелы, вопросительные и восклицательные знаки. Заставляет меня ежедневно убивать дизайнера!
  • Не используйте ключевые слова синтаксиса в качестве имен объектов, это вызовет головную боль, пытаясь получить от них данные. Я ненавижу заключать имена объектов в [index], это два ненужных символа, которые мне не нужно было набирать, черт возьми!
19
ответ дан 26 November 2019 в 21:44
поделиться

Одна вещь, о которой я еще не упоминал:

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

. Если вы что-то опечатали при создании, исправьте это, как только заметите это. Не тратьте годы на то, чтобы помнить, что в этой таблице UserName на самом деле является Usernmae. Это намного проще исправить, когда против него написано не так много кода.

Никогда не используйте подразумеваемые соединения (синтаксис запятой), всегда указывайте соединения.

13
ответ дан 26 November 2019 в 21:44
поделиться

Мне нравится наше соглашение об именах таблиц:

People Table
PEO_PersonID
PEO_FirstName 
...

Это помогает сделать большие запросы более удобочитаемыми. и объединения имеют немного больше смысла:

Select * -- naughty!
From People
Join Orders on PEO_PersonID = ORD_PersonID
--...

я полагаю, что скорее не то, что такое соглашение об именах, а согласованность именования.

0
ответ дан 26 November 2019 в 21:44
поделиться

Если взять слово «база данных» как «продукт SQL», я отвечу: «Слишком много, чтобы упоминать. Вы могли бы написать целую книгу на эту тему». К счастью, у кого-то есть.

Мы используем стиль программирования SQL Джо Селко (ISBN 978-0120887972): «эта книга представляет собой набор эвристик и правил, советов и приемов, которые помогут вам улучшить стиль программирования SQL и повысить его квалификацию, а также для форматирования и написания переносимых, читаемый, поддерживаемый код SQL ».

Среди преимуществ этого подхода:

  • этот парень знает об этом больше, чем я (есть ли еще одна книга по эвристике SQL?!);
  • работа уже выполнена, например, я могу дать книга для кого-нибудь из команды, чтобы прочитать и сослаться на него;
  • если кому-то не нравится мой стиль программирования, я могу обвинить кого-то другого;
1
ответ дан 26 November 2019 в 21:44
поделиться

Документируйте все; Документация вики-типа проста в установке, а программное обеспечение бесплатное.

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

Затем определите стандарт и версию базы данных, над которой вы собираетесь работать. Определить стандарты для элементов кода (представления, функции и т.д.), именования базы данных; соглашения об именах для столбцов, таблиц; соглашения о типах столбцов; шаблоны кодирования.

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

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

1
ответ дан 26 November 2019 в 21:44
поделиться

13- Evaluate your queries

Thats true. Sometimes you don't get what you wanted.

For me, it's always useful to name the tables and fields with their exact content and (for us) in clear spanish and using Upper Camel Case, with no whitespaces:

User Name: NombreUsuario

First Last Name: ApellidoPaterno

Second Last Name: ApellidoMaterno

etc etc

1
ответ дан 26 November 2019 в 21:44
поделиться

В MS-SQL у меня всегда были объекты, принадлежащие dbo., И я префикс для вызовов этих объектов с помощью dbo.

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

1
ответ дан 26 November 2019 в 21:44
поделиться

Я согласен практически со всем, что вы там написали, кроме №5. Я часто использую префиксы для таблиц и хранимых процедур, потому что системы, которые мы разрабатываем, имеют множество различных функциональных областей, поэтому я буду стремиться префикс таблиц и sprocs с идентификатором, который позволит им хорошо группироваться в Management Studio в зависимости от того, в какой области они принадлежат.

Пример: cjso_Users, cjso_Roles, а затем у вас есть routing_Users, routing_Roles. Это может звучать как репликация данных, но на самом деле две разные таблицы пользователей / ролей предназначены для совершенно разных функций системы (cjso будет для клиентского приложения электронной коммерции, а маршрутизация - для сотрудников и дистрибьюторов, которые используют маршрутизацию. система).

0
ответ дан 26 November 2019 в 21:44
поделиться

Некоторые другие (хотя и небольшие) комментарии, которые стоит бросить в стену ...

Схемы базы данных SQL Server могут быть полезны как для организации таблиц и хранимых процедур, так и для контроля безопасности.

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

Используйте GUID для идентификаторов строк для всех строк для проектов с требованиями оффлайн / синхронизации.

2
ответ дан 26 November 2019 в 21:44
поделиться
  • Таблицы именуются в единственном числе, в нижнем регистре, без подчеркивания, без префикса
  • Поля также в нижнем регистре, без подчеркивания, без префикса
  • Хранимые процедуры с префиксом "st_" (хорошо сортируются)
  • Представления, которые обрабатываются как таблицы, не имеют префикса.
  • Представления, созданные для специальных отчетов и т. Д., Имеют префикс "v"
  • Индексированные представления, созданные для повышения производительности, имеют префикс "ixv"
  • Все индексы имеют целевой имена (без автоматического именования)
  • Сильно предпочитайте уникальный идентификатор (с последовательным приращением) int IDENTITY для суррогатных ключей
  • Не ограничивайте искусственно поля VARCHAR / NVARCHAR 100 или 255. Дайте им возможность дышать. Это не 1980-е годы, поля не хранятся с заполнением до максимальной длины.
  • Минимальный стандарт 3NF
  • Предпочитать объединение таблиц с внешними ключами на уровне столбцов: многие 1: Предположения m подвергаются сомнению по мере роста системы со временем.
  • Всегда используйте суррогатные ключи, а не естественные ключи, в качестве первичного ключа. Все предположения о «естественных» ключах (SSN, имена пользователей, номера телефонов, внутренние коды и т. Д.) В конечном итоге будут оспорены.
2
ответ дан 26 November 2019 в 21:44
поделиться

Хороший дизайн базы данных и нормализация .

2
ответ дан 26 November 2019 в 21:44
поделиться

Несколько лайков и антипатий.

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

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

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

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

s всегда следует помещать в начало строки при выполнении объявления параметров или переменных. Очевидно, это сделало его более читабельным, однако я нашел его полным кошмаром.

s всегда следует помещать в начало строки при выполнении объявления параметров или переменных. Очевидно, это сделало его более читабельным, однако я нашел его полным кошмаром.

3
ответ дан 26 November 2019 в 21:44
поделиться
  1. Не используйте имена типов в именах полей. Ребята постарше будут помнить старый стандарт MS для lpszFieldName и последовавшую за этим глупость.

  2. Используйте описательные имена полей, которые следуют обычным языковым соглашениям. Например, «FirstName» вместо «NameFirst»

  3. Каждое слово в имени поля пишется с заглавной буквы

  4. Без подчеркивания

  5. Не используйте обычные ключевые слова, такие как «Index»

  6. Не используйте префикс НИЧЕГО с типом объекта . Например, мы НЕ используем tblCustomers или spCustomersGet. Они не обеспечивают хорошую сортировку и предоставляют нулевое значение.

  7. Используйте схемы для определения отдельных областей базы данных. Например, отдел продаж, клиенты и сотрудники. Это позволит избавиться от большинства используемых людьми префиксов.

  8. Любые петли следует рассматривать с подозрением. Обычно есть способ лучше, основанный на наборе.

  9. Используйте виды для сложных объединений.

  10. По возможности избегайте сложных объединений. Было бы более эстетично иметь таблицу CustomerPhoneNumbers; но честно говоря, сколько телефонных номеров нам действительно нужно хранить? Просто добавьте поля в таблицу «Клиенты». Ваши запросы к БД будут быстрее и их будет намного легче понять.

  11. Если одна таблица вызывает поле «EmployeeId», то КАЖДАЯ ТАБЛИЦА, которая ссылается, должна использовать это имя. Его не нужно называть CustomerServiceRepId только потому, что он находится в таблице расширений.

  12. Почти все таблицы имеют окончание «s». Например: клиенты, заказы и т. Д. В конце концов, таблица содержит много записей ...

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

  14. Связывающие таблицы, которые поддерживают отношения "многие ко многим", имеют обе связанные таблицы в имени. Например, SchoolsGrades. По названию таблицы очень легко понять, что она делает.

  15. БУДЬТЕ ПОГОДНЫ. Если вы начнете идти по одному пути со своими соглашениями, не меняйте лошадей на полпути, если только вы не хотите реорганизовать всю предыдущую работу. Это должно затормозить любые идеи типа «было бы здорово, если ...», которые в конечном итоге вызывают путаницу и огромное количество переделок.

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

7
ответ дан 26 November 2019 в 21:44
поделиться

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

7
ответ дан 26 November 2019 в 21:44
поделиться

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

Это также действительно помогает повысить эффективность планов выполнения запросов.

5
ответ дан 26 November 2019 в 21:44
поделиться

Все пишут запросы SQL (представления, хранимые процедуры и т. Д.) В одном и том же базовом формате. Это действительно помогает усилиям по развитию / поддержке в будущем.

3
ответ дан 26 November 2019 в 21:44
поделиться

Согласованные стандарты именования. Наличие всех на одной странице, использование одного и того же формата (будь то Camel Case, определенные префиксы и т. Д.) Помогает в обеспечении точного обслуживания системы.

3
ответ дан 26 November 2019 в 21:44
поделиться

Я всегда стараюсь не использовать тип в имени поля - «sFirstName», «sLastName» или «iEmployeeID». Хотя сначала они совпадают, но если что-то изменится, они будут рассинхронизированы, и изменить эти имена позже станет огромной головной болью, так как вам также придется изменить зависимые объекты.

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

6
ответ дан 26 November 2019 в 21:44
поделиться

В дополнение к нормализации до 3NF или BCNF (подробнее об этом в этом вопросе ) я обнаружил, что следующие полезны:

  • Называть таблицы как существительные во множественном числе
  • Называть столбцы как сигулярные

Итак, в таблице «Люди» есть столбец «PersonID» .

  • В составных ключах нет ничего плохого, пока действуют правила 3NF или BCNF. Во многих случаях (например, в случае «многие ко многим») это совершенно желательно.
  • Избегайте повторения имени таблицы в именах столбцов. В любом случае peoplePersonID лучше записывать как table.column, он гораздо более читабелен и, следовательно, самодокументируется. People.PersonID лучше, по крайней мере, для меня.
  • ON DELETE CASCADE следует использовать очень осторожно .
  • Помните, что NULL означает одно из двух: либо неизвестно, либо неприменимо.
  • Помните также, что значения NULL оказывают интересное влияние на соединения, поэтому практикуйте внешние соединения LEFT, RIGHT и FULL.
2
ответ дан 26 November 2019 в 21:44
поделиться

не забывайте регулярно делать резервные копии баз данных.

8
ответ дан 26 November 2019 в 21:44
поделиться
  • Назовите все ограничения
9
ответ дан 26 November 2019 в 21:44
поделиться

Мои стандарты для Oracle:

  • Ключевые слова всегда в ВЕРХНЕМ РЕГИСТРЕ;
  • Имена объектов базы данных всегда в нижнем регистре;
  • Подчеркивание заменяет пробелы (т. Е. Не будет любые соглашения о верблюжьих регистрах, которые распространены, скажем, на SQL Server);
  • Первичные ключи почти всегда будут называться id;
  • Ссылочная целостность будет обеспечена;
  • Целочисленные значения (включая идентификаторы таблиц) будут обычно всегда ЧИСЛО (19,0). Причина в том, что это соответствует 64-битному целому числу со знаком, что позволяет использовать длинный тип Java вместо более неудобного BigInteger;
  • Несмотря на неправильное добавление "_number" к некоторым именам столбцов, тип таких столбцов будет VARCHAR2, а не числовой. Типы чисел зарезервированы для первичных ключей и столбцов, с которыми вы производите арифметические операции;
  • Я всегда использую технические первичные ключи; и
  • Каждая таблица будет иметь свою собственную последовательность для генерации ключей. Имя этой последовательности будет _seq.

В SQL Server единственной модификацией является использование верблюжьего регистра для имен объектов базы данных (т.е. PartyName вместо party_name).

Запросы будут записываться в несколько строк с одним предложение или условие на строку:

SELECT field1, field2, field2
FROM tablename t1
JOIN tablename2 t2 ON t1.id = t2.tablename_id
WHERE t1.field1 = 'blah'
AND t2.field2 = 'foo'

Если предложение SELECT достаточно длинное, я разделю его по одному полю на строку.

10
ответ дан 26 November 2019 в 21:44
поделиться

SQL в табличном формате.

select a.field1, b.field2
from       any_table   a
inner join blah        b on b.a_id       = a.a_id
inner join yet_another y on y.longer_key = b.b_id
where a.field_3         > 7
and   b.long_field_name < 2;

Частью этого является использование одинаково длинных псевдонимов (в данном примере a, b и y имеют длину 1).

С при таком форматировании я могу быстрее отвечать на распространенные вопросы, например, "какая таблица имеет псевдоним" a "?" и "какие поля присоединяются к таблице T в запрос?" Структура не занимает много времени, чтобы применить или обновить, и я считаю, что это экономит много времени. Мы тратим больше времени на чтение кода, чем на его написание.

2
ответ дан 26 November 2019 в 21:44
поделиться

Убедитесь, что каждый вариант varchar / nvarchar является подходящим.

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

. 1246] Независимо от каких-либо других правил, которые вы можете использовать из приведенных здесь предложений, я бы создал хранимую процедуру в базе данных, которая может запускаться на регулярной основе для определения работоспособности системы для любых правил или стандартов, которые у вас есть (некоторые из них немного специфично для SQL-сервера):

  • Ищите потерянные записи в тех случаях, когда ссылочная целостность системы СУБД по какой-то причине не может использоваться (в моей системе у меня есть таблица процессов и таблица тестов - так что мой системный пакет system_health выглядит для процессов без испытаний,поскольку у меня только односторонняя связь FK)

  • Ищите пустые схемы

  • Ищите таблицы без первичных ключей

  • Ищите таблицы без индексов

  • Ищите объекты базы данных без документации (мы используем SQL Server Расширенные свойства для помещения документации в базу данных - эта документация может быть такой же детальной, как столбец ).

  • Ищите системные проблемы - таблицы, которые необходимо архивировать, исключения, которые не являются частью обычная ежемесячная или ежедневная обработка, некоторые общие имена столбцов со значениями по умолчанию или без них (например, CreateDate).

  • Ищите недетерминированные UDF.

  • Ищите комментарии TODO, чтобы убедиться, что код в БД не имеет непроверенных или предварительно -код выпуска.

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

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

  • Ищите недетерминированные UDF.

  • Ищите комментарии TODO, чтобы убедиться, что код в БД выполняет у вас каким-то образом нет непроверенного или предварительного кода.

  • Все это можно автоматизировать, чтобы дать вам общую картину состояния системы.

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

  • Ищите недетерминированные UDF.

  • Ищите комментарии TODO, чтобы убедиться, что код в БД выполняет у вас каким-то образом нет непроверенного или предварительного кода.

  • Все это можно автоматизировать, чтобы дать вам общую картину состояния системы.

    5
    ответ дан 26 November 2019 в 21:44
    поделиться

    Имя таблицы совпадает с именем первичного ключа и ключом описания

    Совсем недавно, после многих лет согласия с этим, я покинул корабль, и теперь в каждой таблице есть столбец «ID».

    Да, я знаю, при связывании таблиц это ужасно! Но то же самое происходит с привязкой ProductID к ProductID, так что зачем лишняя типизация?

    Это:

    SELECT p.Name, o.Quantity FROM Products p, Orders o WHERE o.ProductID = p.ID
    

    Немного лучше, чем это:

    SELECT p.Name, o.Quantity FROM Products p, Orders o WHERE o.ProductID = p.ProductID
    

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

    1
    ответ дан 26 November 2019 в 21:44
    поделиться

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

    1
    ответ дан 26 November 2019 в 21:44
    поделиться

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

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

    Первичный ключ в таблице имеет то же имя, что и таблица, с суффиксом _PK. Иностранные ключи имеют то же имя, что и соответствующий им первичный ключ, но с суффиксом _FK. Например, первичный ключ в таблице "Продукт" называется "Product_PK"; в таблице "Заказы" соответствующий внешний ключ называется "Product_FK". Я подобрал эту привычку у другого моего друга по DBA, и пока что она мне нравится.

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

    1
    ответ дан 26 November 2019 в 21:44
    поделиться

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

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

    1
    ответ дан 26 November 2019 в 21:44
    поделиться
    Другие вопросы по тегам:

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