Лучшая практика посещений строк журнала SQL Server - PullRequest
2 голосов
/ 14 октября 2019

В настоящее время у меня есть база данных для статей, которая отслеживает наиболее читаемую статью в течение определенного времени, увеличивая счетчик посещений на page_load. Текущий счетчик «посещений» - это столбец в таблице articles (см. Ниже):

id | title  | description | visits | creation_date
---+--------+-------------+--------+-----------------
1  | test1  | test test.. | 10     | 2019-01-01
2  | test2  | test test.. | 20     | 2019-01-01

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

  1. Удалите счетчик Visits из таблицы Articles
  2. Создайте новую таблицу article_visits с двумя столбцами: article_id и date

Статьи

id | title | desc | creation_date
---+-------+------+---------------
1  | test1 | desd | 2019-01-01
2  | test1 | desd | 2019-01-01

article_visits

article_id | visit_date
-----------+----------------------
1          | 2019-01-01
1          | 2019-01-01
1          | 2019-01-01
1          | 2019-01-01
1          | 2019-01-01
1          | 2019-01-01
2          | 2019-01-01
2          | 2019-01-01
2          | 2019-01-01

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

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

Ответы [ 4 ]

2 голосов
/ 14 октября 2019

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

Кроме того, я мог бы добавить полный столбец datetime или datetime2 для фактической отметки времени (в дополнение к текущему столбцу даты, а не вместо него, так как вы хотите выполнить агрегирование только по датеа предварительное вычисление этого значения может повысить производительность) и, возможно, несколько других столбцов, таких как IP-адрес и реферер. Затем вы можете использовать эти данные для дополнительных целей, таких как аудит, отслеживание рентабельности инвестиций реферера / рекламодателя и т. Д.

2 голосов
/ 14 октября 2019

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

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

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

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

  • Процесс, который периодически суммирует все данные (скажем, данные).
  • Процесс, который суммирует данные на основе периодов за этот период (скажем, ежедневная сводка).
  • Материализованное / индексированное представление, которое позволяет базе данных поддерживать данные в рабочем состоянии. на сегодняшний день.
0 голосов
/ 15 октября 2019

Текущий Articles таблица не находится в Normalized form.

Я скажу, что размещение visits столбца в Articles Таблица не является правильным способом De-Normalization.

ТекущийТаблица Articles не только создает проблему взаимоблокировки, но и вы не можете получить так много других типов отчетов. Daily Visit Report, Weekly Visit Report.

Создание Article_visits таблицы - очень хороший ход. Это будет очень часто обновляться.

Мой Article_visits дизайн

article_visit_id |   article_id | visit_date           | visit_count
-----------------+--------------+----------------------+----------------------
1                |    1         | 2019-01-01           | 6
2                |    2         | 2019-01-01           | 3

Здесь Article_Visit_id равен int identity(1,1), что также Clustered Index.

Create NonClustered Index NCI_Articleid_date ON Article_visits(article_id,visit_date)
GO

Короче говоря, создание CI для article_id,visit_date будет дорогостоящим делом.

Если для этой article записи на эту дату не существует записи, вставьте visit_count 1, если она существует, затем обновите visit_count, т. Е. Увеличьтена 1.

  1. Нормализовано.
  2. Вы можете создать любой вид отчета, текущее требование + любое будущее требование.
  3. Вы можете показать статью мудрым подсчетом. ЗапросЭто так просто и быстро.
  4. Вы можете получать еженедельно, даже получать годовой отчет так просто и без Indexed View.

Фактический дизайн таблицы,

Create Table Article(Articleid int identity(1,1) primary key
,title varchar(100) not null,Descriptions varchar(max) not null
 ,CreationDate Datetime2(0))
    GO

 Create Table Article_Visit(Article_VisitID int identity(1,1) primary key,Articleid int not null ,Visit_Date datetime2(0) not null,Visit_Count int not null) 
    GO

--Create Trusted FK
    ALTER TABLE Article_Visit
    WITH NOCHECK
    ADD CONSTRAINT FK_Articleid FOREIGN KEY(Articleid) 
    REFERENCES Article(Articleid) NOT FOR REPLICATION;
    GO


    --Create NonClustered Index NCI_Articleid_Date on 
    -- Article_Visit(Articleid,Visit_Date)
    --Go

    Create NonClustered Index NCI_Articleid_Date1 on 
     Article_Visit(Visit_Date)include(Articleid)
    Go

Создайте Trusted FK, чтобы получить преимущество поиска индекса (вкратце). Я думаю, NCI_Articleid_Date больше не требуется, поскольку Articleid является Trusted FK.

Deadlock Issue: Trusted FK также было создано для преодоления проблемы тупика. Это часто происходит из-за плохого Application code или UN-Optimized Sql query или Bad Table Design. Помимо этого также есть несколько других веских причин, таких как обработка Race Condition. Это довольно сложная вещь для DBA. Если тупик слишком сильно болит, то после устранения вышеупомянутой причиныВам может потребоваться Isolation Level.

Многие проблемы тупиковой ситуации автоматически обрабатываются самим сервером Sql.

На сайте DEASLOCK REASON . * 1067 опубликовано так много статей. *

Я не думаю, что размер таблицы - это проблема

Table size - это большая проблема. Шансы Deadlock в обоих дизайнах очень очень малы. Но вы всегда будетеперед лицом demerit из Big Size таблицы.

Я говорю вам прочитать еще несколько статей.

Я надеюсь, что это ваша точно такая же реальная таблица с тем же типом данных?

Как часто обе таблицы будут вставляться / обновляться?

Какая таблица будет запрашиваться чаще?

Одновременное использование каждой таблицы.

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

Какое отношение между Visitorid и Artcileid?

0 голосов
/ 14 октября 2019

Мне интересно понять, почему вы получаете тупиковую блокировку. Должно быть так, что платформа db должна уметь одновременно обрабатывать update tablename set field = field + 1. Здесь таблица или строка будут блокироваться, а затем освобождаться, но время не должно быть достаточно большим, чтобы вызвать ошибку взаимоблокировки.

ВЫ МОЖЕТЕ получить ошибку взаимоблокировки, если вы обновляете или блокируете более одной таблицы с транзакцией черезнесколько таблиц особенноесли вы делаете их в другом порядке.

Итак, вопрос в том, что ... в исходном коде вы ссылаетесь на несколько таблиц, когда выполняете оператор обновления? Решение может быть таким же простым, как сделать ваше обновление атомарным для одной таблицы.

Однако я согласен - описанная вами таблица более функциональна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...