LINUX.ORG.RU
ФорумTalks

[задачка для ума][бд] Проектирование

 


0

1

Предлагаю вашему вниманию следующую задачку.

Предположим что нам необходимо написать небольшую базу данных для учёта абитуриентов. У нас есть основная таблица (для простоты), куда мы будем вставлять записи о делах абитуриентов.

Условие:

Абитуриент имеет право подать на бюджетную (и/или) на платную форму обучения. Т.е. в бумажном деле абитуриента может находится сразу 2 заявления. Остальные критерии поступления неважны.

На вскидку можно предложить 2 варианта реализации поля «Форма обучения».

1. Для «Форма обучения» отводится 1 поле. Значения представляются как

   0 -  "не выбрано"
   1 -  "бюджет"
   2 -  "платно"

CREATE TABLE `tb_main` (
   ...
   `edu_form` int,
   ...
);

2. Для каждой формы обучения отводится своё поле, где

   0 - "Нет заявления"
   1 - "Есть заявление"

CREATE TABLE `tb_main` (
   ...
   `ef_budget` int,
   `ef_payment` int,
   ...
);

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


Аргументируйте, какой вариант выбрали бы вы.


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

Можете предложить свой вариант.


вообще можно таблицу «абитуриент» поделить на две таблицы - «абитуриент» и «заявления абитуриента», а в таблице «заявления абитуриента» сделать поле «тип заявления», как в первом варианте

ArsenShnurkov
()

я бы выбрал вариант с отдельной таблицей, содержащей возможные формы обучения — если завтра вуз начнёт предоставлять ещё заочное и очно-заочное, плюс вечернее — можно будет просто добавить их в таблицу. Плюс отдельная таблица, в которой указывается, какой абитуриент на какую форму подал документы, примерно так: [request_id, abiturient_id, form_id], с возможностью указывать для каждого абитуриента несколько записей, то есть уникальный ключ по abiturient_id + form_id, там же можно хранить дату подачи заявления и его номер, например.

name_no ★★
()
Ответ на: комментарий от rg-400

Поскольку решение у меня уже есть, я предложил эту задачу здесь.

guilder
() автор топика
Ответ на: комментарий от name_no

Плюс отдельная таблица, в которой указывается,

какой абитуриент на какую форму подал документы


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

ArsenShnurkov
()
Ответ на: комментарий от VirRaa

Почему вы считаете что это простая задачка.

По этой таблице вам необходимо будет построить «Простыни»(разбалловка по 10 баллов), Экзаменационные ведомости и кучу отчётов.

guilder
() автор топика

Абитуриентота на ЛОРе

Siado ★★★★★
()
Ответ на: комментарий от ArsenShnurkov

> кто и как будет определять идентичность абитуриента по двум разным заявлениям

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

name_no ★★
()
Ответ на: комментарий от name_no

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

Вы абсолютно правы.

guilder
() автор топика
Ответ на: комментарий от guilder

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

VirRaa ★★★
()
Ответ на: комментарий от VirRaa

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

Правила приёма в вузы в моей (РБ) стране меняются каждый год. По вашему стоит каждый год писать новое приложение?

guilder
() автор топика
Ответ на: комментарий от VirRaa

> Давай ещё подумаем, как лучше лампочку вкручивать…

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

name_no ★★
()
Ответ на: комментарий от rg-400

> ...и куча бабла

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

name_no ★★
()
Ответ на: комментарий от name_no

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

чтобы вкрутить лампочку, тащемта.


мало, минимум 20 человек, а то и больше

1 маркетолог по рынку источников света
1 маркетолог по рынку патронов и прочей инфраструктуры
1 руководитель группы аналитической поддержки маркетологов
....1 разработчик системы сбора данных (ввод данных)
....1 администратор БД (хранение данных)
....1 аналитик по обработке данных
....1 программист отчетов
1 архитектор, чтобы совпал разъем лампочки и патрона
1 бизнес-аналитик, чтобы предоставить обоснование целесообразности проекта
1 менеджер проекта, чтобы координировать усилия
1 руководитель фундаментальных исследований
....1 ученый по наносветодиодам
....1 ученый по ртутным лампам
....1 ученый по лазерным источникам света
....1 ученый по мониторингу перспективных направлений
2 уборщицы
1 курьер
1 офис-менеджер
1 повар
2 сисадмина

ArsenShnurkov
()
Ответ на: комментарий от kranky

> Заведи варчар переменную и пиши в неё 'platnoe', 'budjetnoye', 'budjetnoye i platnoe' итд.

да-да, а потом в программе парсить на подстроки и передавать подстроки в фабрику, которая будет на основании названия генерировать соответсвующий класс Form::Platnoe, Form::Budgetnoje и тп, с общим интерфейсом (как его там... полиморфизьмЪ), например; и потом из этих классов генерить html, который можно будет выводить на принтер тащемта.

name_no ★★
()
Ответ на: комментарий от ArsenShnurkov

> мало, минимум 20 человек, а то и больше

1 маркетолог по рынку источников света

я сказал «программистов», маркетологов я не считал. традиционно считается, что каждый программист кормит ещё не меньше 5 других сотрудников, так что 8 программистов — это от 40 человек штат.

name_no ★★
()
Ответ на: комментарий от guilder

Посему надо один раз сесть и составить нормальную архитектуру БД. И в этом нет никакой сложности, ибо архитектура там не может быть запутанной… там всё прозрачно, очевидно, элементарном. Нейм_но тебе уже давно сказал решение, опять же, элементарное. А если у тебя абсолютно нет опыта, и ты начинающий кул-прогер, то решай задачу — никто тебе не мешает. Но не стоит делать из элементарщины загадку века.

Как-то так.

VirRaa ★★★
()
Ответ на: комментарий от kranky

> Заведи варчар переменную и пиши в неё 'platnoe', 'budjetnoye', 'budjetnoye i platnoe' итд.

Тогда уж лучше сразу блоб в который скидывать отсканированные заявления абитуриента.

Evgueni ★★★★★
()

IMHO лучше это вынести в отдельную таблицу (уникальный id абитуриента, id формы обучения)

Evgueni ★★★★★
()
Ответ на: комментарий от VirRaa

> Забыл неделю на разработку архитектуры, и только потом уже реализация.

не «забыл», а «умолчал» ))

name_no ★★
()

>0 - «не выбрано»

1 - «бюджет»

2 - «платно»



а в наше время были другие формы - дневная, вечерняя и заочная... эхх.

k0l0b0k ★★
()
Ответ на: комментарий от k0l0b0k

> а в наше время были другие формы - дневная, вечерняя и заочная... эхх.

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

name_no ★★
()
Ответ на: комментарий от k0l0b0k

Это не формы обучения, а виды источников финансирования (другой справочник).

Можно быть на платном дневном, можно на платном вечернем, а можно на платном заочном...

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

ArsenShnurkov
()

Я бы делал так:

{
    type: 'Аббитуриент',
    name: 'Пупкин',
    payment_request: 'request-12345',
    budget_request: 'request-12346',
}
baverman ★★★
()
Ответ на: комментарий от kranky

> Заведи варчар переменную и пиши в неё 'platnoe', 'budjetnoye', 'budjetnoye i platnoe' итд.

Это не круто. Лучше сделать одну запись с одним полем varchar(max) и хранить там вообще всех абитурентов вместе со всеми заявлениями в виде свободного текста. ;)

sign
()

Основная таблица абитуриентов, связанная - его документы. В связанной хоть десять+ документов для каждого абитуриента. Связь master-detail.

tux2002
()
Ответ на: комментарий от VirRaa

1. решение уже 3 года как есть 2. задал задачу потому что сейчас затачиваю прогу под новые правила приёма.

guilder
() автор топика

1)

Второй вариант - это вектор, некий «composite state»
Первый вариант - это флаг состояния в автомате.

Может ли человек быть одновременно на бюджете и на «платном»? Вроде как нет. Например, критерий «завалить сессию» переводит состояние студента из «бюджета» в «платное», или вообще ставит в «удалён».

Значит надо брать флаг, и значит вариант 1.

2) К первому варианту хорошо приделывается табличка с локализацией. Например, ты выбираешь значение edu_form, и тут же вторым запросом выясняешь, как это значение флага звучит «по-человечески».

3) имя «payment» выглядит криво. Поле состояния должно называться как состояние. «Платеж» - это не названия состояния.

stevejobs ★★★★☆
()
Ответ на: комментарий от ArsenShnurkov

> Это не формы обучения, а виды источников финансирования (другой справочник).

1С?!!!!

Палитесь, товарисчъ...

stevejobs ★★★★☆
()
Ответ на: комментарий от stevejobs

>Например, критерий «завалить сессию» переводит состояние студента из «бюджета» в «платное», или вообще ставит в «удалён».

у меня таблица абитуриентов, про студентов будет отдельная задача.

Может ли человек быть одновременно на бюджете и на «платном»? Вроде как нет.

вы абсолютно правы и первый кто обратил на это внимание. абитуриент участвует только в 1 конкурсе и переходит во 2 если не прошёл по первому. Также во время совмещённого приёма документов человека имеющего 2 заявления нельзя отображать в платном конкурсе - его там нет.

guilder
() автор топика

>2. Для каждой формы обучения отводится своё поле, где

`ef_budget` int,

Я бы выбрал опцию «публично наказать проектировщика перед кафедрой гуманитарных наук», потому что не знать про boolean и отводить 4 байта под флаг «да-нет» может только *неразборчиво*.

Коэффициент интеллекта в расчете на особь риальне падает, потому как назвать такое «задачей для ума», скажем в 2004, мало кто отважился бы.

linuxfan
()
Ответ на: комментарий от linuxfan

>Я бы выбрал опцию «публично наказать проектировщика перед кафедрой гуманитарных наук», потому что не знать про boolean и отводить 4 байта

да?, а заявления при котором человек зачисляется на 2 курс вы как тоже boolean и для всех последующих курсов тоже?

и я не указывал здесь название бд , так что int здесь гипотетический

guilder
() автор топика
Ответ на: комментарий от guilder

>а заявления при котором человек зачисляется на 2 курс вы как тоже boolean и для всех последующих курсов тоже?

Мне процитировать твой пассаж про флаг или сам осознаешь внутреннее противоречие своих постов?

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

linuxfan
()
Ответ на: комментарий от linuxfan

>А при появлении, как уже выше писали, очных и прочих форм обучения, в табличку будем новые столбцы добавлять?

Вообще-то это «отделение», а не «форма».

guilder
() автор топика
Ответ на: комментарий от guilder

Я ещё раз повторяю, что это задачка для ума школьника, 9 класс… раздувать тут тред с умным лицом мега-девелопера, по–крайней мере выглядит убого.

VirRaa ★★★
()

Для такого тривиального расклада пофиг.

0 - «не выбрано»

Вводить ещё один нуль? Не нужно.

Очень простая задача. Думал, намного лучше будет.

mclaudt
()
Ответ на: комментарий от VirRaa

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

P.S. я не мега-девелопер.

guilder
() автор топика
Ответ на: комментарий от guilder

Я вообще не смотрел ни в какую сторону — это раз.
А во–вторых тут больше половины издевались над тобой, мега-девелопер.

VirRaa ★★★
()
Ответ на: комментарий от VirRaa

> Я вообще не смотрел ни в какую сторону — это раз.

Не очень понятно для чего вы тогда написали в этой теме столько постов.

А во–вторых тут больше половины издевались над тобой, мега-девелопер.

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

guilder
() автор топика
Ответ на: комментарий от rg-400

>отдельная таблица где перечислены формы, т.е. модифицированный 1 вариант

+1

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

Alex_A_V ★★
()
Ответ на: комментарий от Alex_A_V

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

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

Чуть позже я напишу как это на самом деле реализовано и почему именно так.

guilder
() автор топика
Ответ на: комментарий от guilder

>Абитуриент в любой момент времени участвует лишь в 1 типе конкурса с одной формой обучения, тогда как заявления может быть 2 ( и туда и туда).

ИМХО этого недостаточно, чтобы сделать выбор. Без полной постановки задачи, предпочтение того или иного способа, будет необоснованным.

Alex_A_V ★★
()

автор, иди перечитывай реляционную алгебру и теорию БД.

exception13 ★★★★★
()
Ответ на: комментарий от Alex_A_V

Абитуриент в любой момент времени участвует лишь в 1 типе конкурса с одной формой обучения, тогда как заявления может быть 2 ( и туда и туда).

ИМХО этого недостаточно, чтобы сделать выбор. Без полной постановки задачи, предпочтение того или иного способа, будет необоснованным.

Этого условия вполне достаточно для данного поля.

Приведу реализованное решение

create table `tb_main` (
   ...
   `edu_form` int,
   `dual_mode` int,
   ...
);

Здесь `edu_form` как и в первом варианте принимает значения [0,1,2], и указывает на текущий конкурс абитуриента.

Поле `dual_mode` указывает на то, есть ли у абитуриента второе заявление если он на бюджете. Тип int выбран для того, чтобы если вдруг введут «СУПЕРМЕГАПЛАТНУЮ» обучения можно было использовать битовые маски.

При данном решение каждый абитуриент всегда будет попадать только в свою таблицу при отображении рейтинга и не будет дублироваться в другой:

Бюджетная таблица
SELECT * FROM `tb_main` WHERE `edu_form`=1 AND ....

Платная таблица
SELECT * ... `edu_form=2` AND ....

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

UPDATE `tb_main` SET `edu_form`=2 WHERE `dual_mode`=1 AND `student`=0 AND `closed`=0;

Здесь поля `student` int - курс зачисления, `closed` - были ли забраны документы.

Также следует учесть что форм обучения много быть не может физически, так как для приёма документов, сверок, зачислений нужна минимум неделя. Поэтому для `dual_mode` подойдёт какой-либо не самый большой int, т.е. в общем случае биты этого поля буду содержать факт наличия заявления на следующий конкурс.

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

guilder
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.