powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Оцените БД.
8 сообщений из 8, страница 1 из 1
Оцените БД.
    #37748920
DmitriyNone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем добрый день.
Сильно не пинайте я тут первый раз.
Ситуация такая - есть задание для БД и пары запросов и есть вариант реализации задания.
Прошу оценить его, и указать ошибки пожелания, думаю конечно, что все будет ужасно, но прошу понять, я только начинающий.
Используется - MS SQL server 2008r2.

Задание:
Задание1. Необходимо спроектировать структуру данных для реализации задачи. Структура
данных должна включать: таблицы, поля, типы данных, ограничения целостности и
уникальности, необходимые ключи, индексы. Необходимо заполнить созданную структуру
тестовыми данными.
Описание: база данных “Школа”.
Преподаватель может вести один или несколько предметов. По совместительству
преподаватель может быть классным руководителем. Быть классным руководителем,
но ничего не преподавать он не может. Школьники учатся в классах не более 30 человек
в классе. Школьники изучают предмет у одного из преподавателей, ведущих данный
предмет. Ежедневное расписание занятий любого класса должно включать не более 6
различных уроков. 1 урок = 1 час (академический) = 40 минут.

2. Необходимо сформировать SQL-запросы, реализующие следующие задачи
а) Посчитать количество учеников, которые изучают математику
б) Посчитать количество рабочих часов (не академических) в неделю
преподавателя “Иванов И.И.”
в) Вывести топ 3 преподавателей, обучающих максимальное количество учеников.
Считать классное руководство также обучением.

Результатом выполнения тестового задания должны являться 2 sql-скрипта. Первый -
создающий структуру данных и заполняющий ее тестовыми данными. Второй скрипт
должен включать в себя sql запросы, реализующие задачи. Допускается использование
любых операторов, поддерживаемых MS SQL Server 2008 R2, но оптимальность запросов
будет являться дополнительным плюсом.

Реализация -

Первый скрипт, создает БД и заполняет тестовыми данными:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
Create database School;
GO
use School;
GO

--Создание базовых таблиц.
create table Disc
(
	ID_disc int primary key identity(1,1),
	disc_Name nvarchar(20) not null
);

create table Groups
(
	ID_group int primary key identity,
	group_name nvarchar(20) not null
);

create table Stud
(
	ID_stud  int primary key identity,
	stud_fio nvarchar(30) not null,
	stud_group int not null
	CONSTRAINT FK_Stud_Group FOREIGN KEY
	REFERENCES Groups (ID_group)
);

create table Teach
(
	ID_teach int,
	teach_fio nvarchar(30) not null,
	teach_disc int,
	teach_group int null,
	primary key (id_teach,teach_disc),
	CONSTRAINT FK_teach_disc FOREIGN KEY
	(teach_disc)
	REFERENCES Disc (ID_disc),
);

create table Schedule 
(
DoW int not null check (DoW > 0 and DoW < 8),
less_num int not null check (less_num > 0 and less_num < 7),
less_teach int,
less_disc int,
less_group int,
CONSTRAINT FK_less_group FOREIGN KEY
(less_group)
REFERENCES Groups (id_group),
CONSTRAINT FK_id_teach_teach_disc FOREIGN KEY
(less_teach,less_disc)
REFERENCES Teach (id_teach,teach_disc),
unique (DoW,less_num,less_teach),
unique (DoW,less_num,less_group),
);
GO

--Создание процедур добавления учителей и учеников, для реализации ограничений по кол-ву учеников в классе,
--и назначения классного руководства преподователю без уроков в расписании.

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

create procedure add_student
    @name nvarchar(30), 
    @group int 
AS 
    SET NOCOUNT ON;
	if (select COUNT(1) from Stud where stud_group = @group) < 30
	begin
		insert into Stud values (@name,@group)
	end;
	else
	begin
		print N'too many students in this group';	
	end;
GO

create procedure add_teacher
	@id int,
	@name nvarchar(30),
	@disc int,
	@group int = null
as
	SET NOCOUNT ON;
	if @group is not null
	begin	
		if exists (select 1 from Schedule where less_teach = @id)
		begin
			insert into Teach values
			(@id,@name,@disc,@group)
		end;
		else
		print N'Этот учитель не может быть классным руководителем.'
	end
	else
		insert into Teach values (@id,@name,@disc,@group)
go


--Добавление тестовых данных в базу.

insert into Disc values 
(N'Eng'),(N'Rus'),(N'Math');

insert into Groups values
(N'A'),(N'B'),(N'C');

exec add_teacher 1,N'Иванов И.И.',2;
exec add_teacher 2,N'teach2',1;
exec add_teacher 2,N'teach2',3;
exec add_teacher 3,N'teach3',3;
exec add_teacher 4,N'teach4',1;

exec add_student N'stud1',1;
exec add_student N'stud2',2;
exec add_student N'stud3',3;
exec add_student N'stud4',1;
exec add_student N'stud5',2;
exec add_student N'stud6',3;
exec add_student N'stud7',1;
exec add_student N'stud8',2;
exec add_student N'stud9',3;
exec add_student N'stud10',1;

insert into Schedule values
(1,1,2,1,1),
(1,2,1,2,2),
(1,3,2,3,3),
(1,4,3,3,1),
(1,5,1,2,3),
(1,6,1,2,1),
(1,1,1,2,2),
(2,6,3,3,1),
(2,5,3,3,1);
go




Второй скрипт, выполняет запросы:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
use School;
go

--Запрос 1 на кол-во учеников изучающих Math.
select COUNT (id_stud) as Math_students from Stud 
where stud_group in
(
	select distinct less_group from Schedule 
	where less_disc in 
	(
		select id_disc from Disc where disc_Name = N'Math'
	)
)


--Запрос 2 на кол-во астрономических часов преподователя Иванова И.И
select COUNT (1)*2/3 as N'Иванов ИИ часов в неделю'
from
(
select dow, less_num,less_group  from Schedule 
where less_teach =
(
	select distinct ID_teach from Teach where teach_fio = N'Иванов И.И.'
)
) as Q


--Запрос 3 на топ 3 учителей по кол-ву обучаемых учеников.
DECLARE @MyCounter int;
SET @MyCounter = 1;

create table tmp (teacher int, students int)

WHILE @MyCounter <= (select MAX (id_teach)from teach)
begin;
	INSERT INTO tmp VALUES
	(@MyCounter,
		(
		select count(id_stud) as 'students of teacher' from stud where stud_group in
		(
			select less_group from Schedule 
			where less_teach = @mycounter
			union 
			select teach_group from Teach  
			where ID_teach = @mycounter
		)
		)
	)
set @MyCounter = @MyCounter + 1;
end;
GO

SELECT distinct top 3 teach_fio, students 
FROM tmp
inner join Teach 
on tmp.teacher = teach.ID_teach 
order by students desc;
GO
DROP TABLE tmp;
GO

	



С нетерпением жду ваших комментариев.
...
Рейтинг: 0 / 0
Оцените БД.
    #37749102
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmitriyNoneПрошу оценить его, и указать ошибки пожелания, думаю конечно, что все будет ужасно, но прошу понять, я только начинающий.
Для начинающего очень и очень неплохо. Первое, что бросается в глаза - Вы зря объединили сущности "учитель" и "предметы, преподаваемые учителем" и нарушили вторую (кажется) нормальную форму. Кроме этого, я либо не врубился, как Вы сделали понятие "классный руководитель", либо там что-то не так. Ну ещё - имхо стоит всегда явно указывать null / not null для колонок. До второго скрипта, честно говоря, не добрался.
...
Рейтинг: 0 / 0
Оцените БД.
    #37749284
Random_Goodman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А табличка (teach_disc) где?
...
Рейтинг: 0 / 0
Оцените БД.
    #37749637
DmitriyNone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarerКроме этого, я либо не врубился, как Вы сделали понятие "классный руководитель", либо там что-то не так.Я добавил поле Teach_Group в таблице Teach с ID группы которой данный учитель является классным руководителем.
_______________________________________

Как я понял, я зря объединил таблицу сущности учителей Teach, и таблицу связей Teach_Disc.
В ближайшее время исправлю эту ошибку. И поправлю исходный пост.
...
Рейтинг: 0 / 0
Оцените БД.
    #37749797
DmitriyNone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
2012-04-12 9:31
Долго переделывал, с утра был завал на работе :)

Не нашел как править свои сообщения, так что придется создать еще один пост.
Если есть люди которые знаю как это сделать, буду рад подсказке.
В случае дальнейших исправлений придется делать так же.

Есть пара вопросов:
1. Нужно ли указывать явно not null на полях primary key, identity, unique ?
2. В данной реализации я объединил поля фамилии, имя и отчества в одно поле, но как я понимаю в действующей базе их желательно разбить на отдельные поля ?

Обновленный скрипт создания таблиц и заполнения данных:
Таблица Teach была разбита на 2 - таблицу сущности учителей Teach и таблицу связей между учителями и предметами Teach_Disc.
Так же было добавлено ограничение на уникальность поля Teach_fio таблицы Teach.

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

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
--Создание базовых таблиц.
create table Disc
(
	ID_disc int primary key identity(1,1),
	disc_Name nvarchar(20) not null
);

create table Groups
(
	ID_group int primary key identity(1,1),
	group_name nvarchar(20) not null
);

create table Stud
(
	ID_stud  int primary key identity(1,1),
	stud_fio nvarchar(30) not null,
	stud_group int not null
	CONSTRAINT FK_Stud_Group FOREIGN KEY
	REFERENCES Groups (ID_group)
);

create table Teach
(
	ID_teach int primary key identity(1,1),
	teach_fio nvarchar(30) not null unique,
	teach_group int null,
);

create table Teach_Disc
(
TD_teach int not null,
TD_disc int not null,
constraint FK_TD_teach_ID_teach foreign key
(TD_teach)references Teach (ID_teach)
on delete cascade,
constraint FK_TD_disc_ID_disc foreign key
(TD_disc)references Disc(ID_disc),
unique (TD_teach,TD_disc)
);


create table Schedule 
(
DoW int not null check (DoW > 0 and DoW < 8),
less_num int not null check (less_num > 0 and less_num < 7),
less_teach int not null,
less_disc int not null,
less_group int not null,
CONSTRAINT FK_less_group FOREIGN KEY
(less_group)
REFERENCES Groups (id_group),
CONSTRAINT FK_td_teach_td_disc FOREIGN KEY
(less_teach,less_disc)
REFERENCES Teach_Disc (td_teach,td_disc),
unique (DoW,less_num,less_teach),
unique (DoW,less_num,less_group)
);
GO

--Создание процедур добавления учителей и учеников, для реализации ограничений по кол-ву учеников в классе,
--и назначения классного руководства преподователю без уроков в расписании.

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

create procedure add_student
    @name nvarchar(30), 
    @group int 
AS 
    SET NOCOUNT ON;
	if (select COUNT(1) from Stud where stud_group = @group) < 30
	begin
		insert into Stud values (@name,@group)
	end;
	else
	begin
		print N'too many students in this group';	
	end;
GO

create procedure add_teacher
	@name nvarchar(30),
	@group int = null
as
	SET NOCOUNT ON;
	if @group is not null
	begin	
		if exists (select 1 from Schedule where less_teach = (select MAX(ID_teach)+1 from Teach))
		begin
			insert into Teach values
			(@name,@group)
		end;
		else
		print N'Этот учитель не может быть классным руководителем.'
	end
	else
		insert into Teach values (@name,@group)
go

create procedure upd_teacher
	@Name nvarchar(30),
	@group int = null
as
	set nocount on;
	if @group is not null
	begin
		if exists (select 1 from Schedule where less_teach in (select ID_teach from Teach where teach_fio = @Name))
		begin
			update Teach set teach_group = @group 
			where ID_teach = (select ID_teach from Teach where teach_fio = @Name)
		end;
		else 
		print N'Этот учитель не может быть классным руководителем.'
	end
go

--Добавление тестовых данных в базу.

insert into Disc values 
(N'Eng'),(N'Rus'),(N'Math');

insert into Groups values
(N'A'),(N'B'),(N'C');

exec add_teacher N'Иванов И.И.';
exec add_teacher N'teach2';
exec add_teacher N'teach3';
exec add_teacher N'teach4';


insert into Teach_Disc values
(1,2),(2,1),(2,3),(3,3),(4,1)


exec add_student N'stud1',1;
exec add_student N'stud2',2;
exec add_student N'stud3',3;
exec add_student N'stud4',1;
exec add_student N'stud5',2;
exec add_student N'stud6',3;
exec add_student N'stud7',1;
exec add_student N'stud8',2;
exec add_student N'stud9',3;
exec add_student N'stud10',1;

insert into Schedule values
(1,1,2,1,1),
(1,2,1,2,2),
(1,3,2,3,3),
(1,4,3,3,1),
(1,5,1,2,3),
(1,6,1,2,1),
(1,1,1,2,2),
(2,6,3,3,1),
(2,5,3,3,1);
go

exec upd_teacher N'Иванов И.И.',1





С нетерпением жду дальнейших предложений, вопросов и пожеланий :)
...
Рейтинг: 0 / 0
Оцените БД.
    #37751289
Random_Goodman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
DmitriyNone:
1. Нужно ли указывать явно not null на полях primary key, identity, unique ?
По их сути разве не понятно, что не может быть null???
...
Рейтинг: 0 / 0
Оцените БД.
    #37751591
DmitriyNone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Random_Goodman,
да конечно понятно, просто softwarer писал
>> Ну ещё - имхо стоит всегда явно указывать null / not null для колонок
вот я и спросил на всякий случай.

А вообще по выполнению, что можете сказать ?
...
Рейтинг: 0 / 0
Оцените БД.
    #37754997
DmitriyNone
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
И тишина...
...
Рейтинг: 0 / 0
8 сообщений из 8, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Оцените БД.
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]