Pull to refresh
96
0
Send message
А если эти изменения редки, а вычитка записей за последние 30 дней идет крайне часто? Все зависит от бизнес кейса ;)
И все-таки насчет одного достойного варианта — спорное утверждение. Настройка и поддержка репликации при использовании автоинкрементов — очень неприятное занятие.

Насчет кластерного и первичного — конечно же знаю разницу. И на практике были разные случаи. Например, когда таблица кластеризована по дате изменения объекта, а первичный ключ, естественно, не кластерный.
Скорее всего вы говорите о количестве символов. Т.к. в NVarchar длина символа — 2 байта, то при 8000 байт там как раз 4000 символов. Или я как-то не так трактую technet.microsoft.com/en-us/library/ms186981%28v=sql.105%29.aspx
Прежде чем писать в таком тоне, очень рекомендую самому попытаться написать хотя бы одну статью. И прочитать внимательно критикуемую статью, кстати, тоже.

А теперь по пунктам:
«так как для некоторых ситуаций более предпочтительным может оказаться GUID» — ну хотя бы ма-аленько так про ситуации. Ну хоть парочку для каждого случая, чтобы сориентировать про какие ситуации вообще вам известно.

Ниже вообще-то расписываются критерии, по которым предпочтительнее GUID, и даже выводы насчет его производительности в плане вставки есть в конце статьи? Или я должен был написать в стиле «Если у вас каталог для интенет магазина — используйте автоинкремент», если у вас база данных пользователей — используйте ГУИД"?

«Приведены преимущества каждого из вариантов...» — вот это вообще не имеет смысла при отсутствии анализа недостатков (что там у нас с джойнами по GUIDу на серьезной базе?).

Да, это указать можно, и в тексте статьи упоминается, как на скорость вычитки могут повлиять непоследовательные ГУИДы

«На практике возможны и другие, более редкие, типы ключа» — действительно, нафиг всю эту тягомотину с денормализацией и подходами к выбору оптимальных ключей! GUID и автоинкремент — наше все! А все остальное — редкая фигня.

Составные ключи (например, версия + номер записи), строковые ключи, иерархические ключи и т.д. Всех их рассмотреть в статье? В каком проценте решений они используются? Статья не претендует на полный гайдлайн по выбору ключей. Заголовок даже на это не намекает. Что за юношеский максимализм?

Теперь о тестах (и в продолжение об обрубках). Судя по ним, автор в базу исключительно пишет. Кстати, давайте поиграем со вставкой, когда таблица не пустая, а содержит миллион записей. С индексом, конечно. А с несколькими индексами? А с кластерным по ключу?

Про миллион записей — это когда вся таблица не умещается в памяти. И этот кейс рассмотрен.

А где, кстати, чтение, обновление, удаление? Джойны опять же?

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

Слова про «ограничение оперативной памяти» есть только на диаграммах. Что сие означает и как (зачем) это было реализовано?

Если прочитать внимательно, то все можно увидеть.

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

Цель этого тестирования — сравнительные цифры, а не абсолютные. Сравнение дает понять как в одних и тех же условиях ведут себя разные варианты. Знание конкретного железа чем-то поможет?
Или жестко лочить доступ к генератору последовательности на этапе получения «резервного» отрезка, что создает bottleneck. Потом, если приложение за время рабочей сессии ничего не добавило, что делать с резервированным отрезком? Если просто игнорировать и всегда получать по возрастанию, то можно быстро дойти до конца 32-битного integer. Можно взять больший тип, но в любом случае решение получается очень хрупкое и плохо масштабируемое.

В реальной жизни в сценариях с репликацией и автоинкрементными ключами на разных репликах вручную прописывают разные диапазоны ключа. Например, на реплике А он стартует с 1, на реплике Б — с 1000000. Но это, опять же, требует ручного вмешательства, плохо масштабируется, и существует вероятность коллизии, когда одна реплика вставит по какой-то причине неожиданно большое количество записей.
Согласен. Строго говоря он работает так:
Creates a GUID that is greater than any GUID previously generated by this function on a specified computer since Windows was started. After restarting Windows, the GUID can start again from a lower range, but is still globally unique.

Взято вот отсюда
Использовался SQL Server 2012, если будет время — попробую разные версии.
Все давно посчитано ;)

en.wikipedia.org/wiki/Globally_unique_identifier

the total number of unique such GUIDs is 2122 (approximately 5.3×1036). This number is so large that the probability of the same number being generated randomly twice is negligible
Внимательно прочитайте статью, там как раз сравнивается перформанс разных вариантов, и затраты на P/Invoke там не видны. Как раз время вставки записей, в которых последовательный GUID ключ генерится через P/Invoke оказывается самым быстрым, потому что затраты на «обработку» непоследовательного ключа на порядки больше. Цитата приведеная выше из моей статьи говорит именно про последовательные гуиды, поэтому я не совсем понял, как предложенный способ генерации ключа соотносится с «последовательным».
В общем случае — повторить попытку. Для пользовательской транзакции это может выражаться в попытке сохранить изменения еще раз, для обработчика сообщений из очереди — сделать автоматический retry несколько раз, прежде чем поместить сообщение в очередь «проблемных» и т.д. Вероятность того, что GUID генератор подряд даст два одинаковых значения практически равна 0. Мне на практике не встречалось ни одного случая коллизий у GUID
Ключ должен быть строго возрастающим. Если вторая часть — рандом, то он уже не дает строгого возрастания, если это не какой-то специальный рандом.
Планирую разобраться с этим более детально и добавить результаты исследования в статью.
Насчет TaskCompletionSource — спасибо за идею, реализация получилась проще, обновил статью.
Отличное решение, спасибо! Добавлю в статью.
Перемерял — результаты у меня особо не изменились — вот код:

        private void TestPerformance(object param)
        {
            Task.Run(() => TestPerformanceInternal());
        }

        private void TestPerformanceInternal()
        {
            int iterations = 1000000;

            var sw = new Stopwatch();
            var csw = new Stopwatch();

            sw.Start();
            for (int i = 0; i < iterations; i++)
            {
                csw.Start();
                _dispatcher.Invoke(() =>
                {
                    csw.Stop();
                });
            }
            sw.Stop();

            long crossThreadTiming = csw.ElapsedMilliseconds;
            long invokeTiming = sw.ElapsedMilliseconds;

            MessageBox.Show(string.Format("Cross-thread timing per call: {0} mcs\nFull invoke timing per call: {1} mcs",
                (double)crossThreadTiming * 1000 / iterations,
                (double)invokeTiming * 1000 / iterations));
        }


Резльутат:
Cross-thread timing per call: 14,762 mcs
Full invoke timing per call: 20,688 mcs

В статье я имел в виду вторую цифру. В этот раз она получилась чуть меньше 26 мкс, но порядок тот же.
Почему-то от Visual Studio глаза не вытекают ;)
Я про это тоже писал ;)
Объяснение реализации паттерна Weak Events выходит за рамки этот статьи, поэтому просто укажу ссылку, где эта тема рассмотрена очень подробно: www.codeproject.com/Articles/29922/Weak-Events-in-C.
1. Делать совсем кастомные контролы для вьюшек и панелей — перебор, для этого UC как раз и предназначены. Делать просто элементы управления типа кастомных комбо-боксов и прочих с помощью UC — да, неправильно.
2.1. Я так и написал, что не имеет отношения непосредственно к WPF, но сказать про эту проблему стОит.
2.2. С TwoWay в примере я погорячился, там лучше написать OneWay, так как это наиболее частый (и, по итогу, проблематичный) сценарий. Подправлю.
5. Не у всех есть Решарпер. А касательно Rx — да, вещь хорошая.
6. В ближайшее время перемеряю и выложу свои тесты. Да, про BeginInvoke, конечно, знаю.
8. Надо подумать

Насчет того, что энтерпрайз давно перешел на ВЕБ — заблуждение, я вижу как минимум 5 больших проектов для очень крупных компаний, которые используют либо только WPF, либо микс WPF и WEB решений для своих нужд. Полностью переходить на ВЕБ никто из них пока не собирается. Не энтерпрайз — тоже немало десктопных утилит используют сейчас WPF. Не стОит забывать, что разработка под Windows 8 и Windows Phone использует те же принципы и некоторые из перечисленных проблем актуальны и там.
Спасибо, совсем не подумал о 6 шарпе. Добавлю в статью nameof тоже.
Большое спасибо! Это интересно, будем «переваривать» )

Information

Rating
Does not participate
Registered
Activity