2016-11-01 2 views
0

Я программирую сайт, на котором хранятся данные сеанса покера. Сессия - это период времени, проведенный в казино, играющем в покер. Сессия содержит информацию, такую ​​как дата/время, чистая прибыль/потеря сеанса и место, где они играли. Тем не менее, часть, с которой я запутался, заключается в том, как обрабатывать сеанс типа. В покере есть два вида игр: кэш-игры и турниры. Каждый из них имеет свои собственные специальные поля только им. Ниже приведен пример таблицы (я удалил ненужные поля):Как нормализовать эту ненормированную таблицу базы данных?

+----+--------------+--------+--------+ 
| id | session type | stakes | buy-in | 
+----+--------------+--------+--------+ 
| 1 | cash   | 1/3 NL | NULL | 
| 2 | cash   | 1/2 NL | NULL | 
| 3 | tournament | NULL | $20 | 
+----+--------------+--------+--------+ 

Как вы можете видеть, мне не нужно buy-in если тип сеанса наличными. Аналогично, если тип сеанса является турниром, мне не нужно поле stakes.

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

+0

оставить одно поле с курсом имя/звание или что-то –

+0

мне нравится первый ответ Lashane, но если только разница в том, один столбец, а все остальное уже написано, я бы просто убедитесь, что session_type является индексом и двигаться дальше к чему-то другому.Нормализация не принесет большого прироста производительности, если у вас нет миллионов строк. – CptMisery

+0

Ваша текущая таблица нормализована, это реализация отношения «is-a». Первое решение Лашана - это еще один способ реализации отношения «is-a». Значения 'null' в вашей реализации прекрасно (и разрешены в нормализации), и вы получите их обратно, когда вы будете делать« select »из сеансов, оставленных join cash_sessions, на ... left join tournament_session on ...', что стандартный запрос, чтобы делать что-либо с вашими данными. Он будет медленнее (из-за соединения), но сохранит некоторое хранилище (на hdd (менее важно) и в ram (что более важно, хотя для соединения требуется также ram)). – Solarflare

ответ

2

Вот один из возможных решений:

сессии:

id_session (PK) 
session_type (Integer/Enum) 

cash_sessions:

id_session (FK) 
stakes 

tournament_sessions:

id_session (FK) 
buy_in 

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

Пример данные:

sessions 
1 1 
2 1 
3 2 

cash_sessions 
1 1/3 NL 
2 1/2 NL 

tournament_sessions 
3 $20 

Другим решением :

сессии:

id_session (PK) 
session_type (Integer/Enum) <- basically useless field for this schema 

атрибуты:

id_attr (PK) 
name (String) 

session_attributes:

id_session (FK) 
id_attr(FK) 
value (String) 

так, вместо того, чтобы думать в терминах "типа сеанса" вы можете изменить свою бизнес-модель, чтобы думать о "атрибуты сеанса" , поэтому разные сеансы могут иметь разные наборы присвоенных атрибутов

Примеры данных:

sessions 
1 1 
2 1 
3 2 

attributes 
1 stakes 
2 buy_in 

session_attributes 
1 1 1/3 NL 
2 1 1/2 NL 
3 2 $20 
Смежные вопросы