база данных, запросы, производительность, кеш - PullRequest
2 голосов
/ 17 января 2011

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

В моем приложении у меня есть список T. Информация в T содержит информацию из нескольких таблиц базы данных.

Есть, конечно, несколько способов сделать это. Два способа, о которых я думаю, это:

слой болтливой базы данных и кеширование:

List<SomeX> list = new List<SomeX>();
foreach(...) {
    list.Add(new SomeX() {
        prop1 = dataRow["someId1"],
        prop2 = GetSomeValueFromCacheOrDb(dataRow["someId2"])
    });
}

Проблема, с которой я столкнулся выше, заключается в том, что если нам нужен список из 500 элементов, он может потенциально выполнить 500 запросов к базе данных. Со всей задержкой в ​​сети и этим. Другая проблема заключается в том, что пользователи могли быть удалены после того, как мы получили список из базы данных, но до того, как мы пытаемся получить его из cache / db, что означает, что у нас будут нулевые проблемы. С которым мы должны справиться вручную. Хорошо, что он хорошо кэшируется.

не болтливый, но не кешируемый:

List<SomeX> list = new List<SomeX>();
foreach(...) {
    list.Add(new SomeX() {
        prop1 = dataRow["someId1"],
        prop2 = dataRow["someValue"]
    });
}

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

не очень болтливый, но все еще кешируемый

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

Ответы [ 2 ]

1 голос
/ 17 января 2011

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

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

"Другая проблема заключается в том, что пользователи могли быть удалены после того, как мы получили список из базы данных, но до того, как мы пытаемся получить его из cache / db, что означает, что у нас будут нулевые проблемы."

Если я возьму эту цитату, то эта цитата:

"Хорошо, что он хорошо кэшируется."

Неверно, потому что вы кэшировали устаревшие данные. Так что отбросьте пока единственное преимущество.

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

Это означает, что вы либо вставляете SQL в код своего приложения, который, по мнению Полиции Мыслей Кодекса, считал «Бесконечным плохим вкусом», либо переходите на sprocs. Либо один работает. Внедрение кода в приложение делает его более удобным, но вы никогда не будете приглашены на более изящные вечеринки ООП.

0 голосов
/ 18 января 2011

Некоторые предложения:

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

Используйте прокси. Допустим, у меня есть объект с 50 свойствами. Сначала вы отображаете список объектов для пользователя. В этом случае я бы создал прокси для наиболее важных свойств и отобразил бы их пользователю, может быть, 2 или три важных свойства, таких как имя, идентификатор и т. Д. Это сокращает объем информации, отправляемой изначально. Когда пользователь действительно хочет отредактировать или изменить объект, тогда сделайте второй запрос, чтобы получить «полный» объект. Получите только то, что вам нужно. Это особенно важно в Интернете при сериализации XML между слоями.

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

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

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

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