2009-07-27 4 views
2

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

table1 (one row = one month) 
------ 
id 
month 
year 
info 


table2 (one row = one year) 
------ 
id 
year 
jan_info 
feb_info 
mar_info 
apr_info 
may_info 
jun_info 
jul_info 
aug_info 
sep_info 
oct_info 
nov_info 
dec_info 

Таблица A

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

Таблица B

  • 10x меньше строк для полного года данных, но
  • Одиночные ряды намного больше
  • Возможно, более трудно добавить больше произвольных данных за месяц

В реальном мире test scenerio Я установил, было 12 000 строк в таблице1 за 10 лет данных, где table2 было 150. Я понимаю, что лучше, вообще говоря, но ВСЕГДА? Я боюсь, что я не обращу внимания на какое-то предостережение, которое больно найти позже, если я возьму на себя один путь. Я даже не рассматриваю использование диска или какой запрос может быть быстрее. Что предпочитает MySQL? Есть ли «правильный» способ? Или есть «лучший» способ?

Спасибо за ваш ввод!

ответ

6

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

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

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

Это действительно зависит от того, за какие данные и откуда. Как правило, первый вариант лучше.

+0

+1, если каждый месяц нужен второй фрагмент информации. – ceejayoz

3

12000 строк за 10 лет данных? Я говорю, что масштаб довольно хорошо, так как 12000 строк практически ничтожны с достойной СУБД.

Как вы используете базу данных? Вы уверены, что вам действительно нужно беспокоиться об оптимизации?

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

+1

+1 для строк 12k, являющихся минимальными. – ceejayoz

0

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

+0

Эх, как второй легче? «SELECT info FROM table1 WHERE month = '09''« кажется так же легко, как вы можете получить ... – ceejayoz

+0

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

+0

Я имею в виду, если он хочет отображать несколько месяцев в том же отчете. Выберите случай, когда месяц = ​​«09», то информация еще нулевой конец, случай, когда mnonth = '10 тогда информация еще нулевой конец от table1 где год = «2009» вице выберите septifo, octinfo из table1 Конечно он может получить даже сложнее, если вы используете данные соглашения для месяцев. – HLGEM

1

«В реальном испытательном испытании, которое я установил, в таблице 1 было 12 000 строк в таблице1 за 10 лет данных, где table2 было 150».

Как? В этом случае должно быть 80 месяцев в году.

+0

Я не дал подробностей, потому что его трудно связать с этим тестом, хотя я думаю, что точка по-прежнему действительна, что ее по меньшей мере в 10 раз больше строк в таблице 1 –

+1

@stabby: нерелевантно. СУРБД оптимизированы для больших объёмов данных (строк). (Кроме того, Access является ** не ** резервной RDBMS, и это единственное место, где я думаю, что будет проблема с 12K + строками) – voyager

1

Поскольку это оптимизирующая проблема, применяется оптимизирующий ответ: это зависит.

Что вы хотите делать с вашими данными?

Таблица A - это нормальная форма, в которой можно хранить данные такого типа.

Для особых случаев Таблица B может пригодиться, но мне нужно подумать, чтобы найти хороший пример.

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

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

Замечание по математике: если вы разделите 12000 на 12 и получите 150 в результате, что-то не так.

0

В целом я бы сказал, что один рекорд в месяц является более общим решением.

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

Другой вопрос, что вы будете делать с этими данными. Вы не говорите, что такое «информация», поэтому просто для обсуждения давайте предположим, что это «продажи за месяц». Вы когда-нибудь захотите сказать: «В какие месяцы у нас было более 1 000 000 долларов в продажах?» ? С одной записью в месяц это простой запрос: «выберите год, месяц с продаж, где month_sales> 1000000». Теперь попробуйте сделать это с помощью таблицы за год. «выберите год,« Янв »из year_sales, где jan_sales> 1000000 union select year, 'Feb' from year_sales, где feb_sales> 1000000 union select year, 'Mar' from year_sales, где mar_sales> 1000000 union ..." и т. д. Или, может быть, d prefer "select year, case when jan_sales> 1000000 then 'Jan = yes' else 'Jan = no', case when feb_sales> 1000000 then 'Feb = yes' else 'Feb = no' ... для оставшихся месяцев .. . from year_sales, где jan_sales> 1000000 или feb_sales> 1000000 или mar_sales> 1000000 ... "Yuck.

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

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