Системы управления базами данных. 8

Министерство  образования и науки Российской Федерации 

МЕЖДУНАРОДНЫЙ ИНСТИТУТ КОМПЬЮТЕРНЫХ ТЕХНОЛОГИЙ 

Кафедра “Системы информационной безопасности” 
 
 
 
 
 
 
 
 
 
 
 

Курсовая  работа 

по дисциплине: «Системы управления базами данных» 
 
 
 
 
 
 
 
 
 
 
 

                      Выполнил:

                      Студент группы Ибо-031

                      Минаков А. Г. 

                      Проверил:

                      к.т.н. доц. 

                      Батищев Р.В. 
                       
                       
                       
                       
                       
                       
                       
                       
                       
                       

Воронеж 2006

 

      Содержание 

Задание кафедры………………………………………………………………………………..…….3

Описание  предметной области……………………………………………………………………..4

Диаграмма «сущность-связь»……………………………………………………………………....8

Нормализованные таблицы в 3 нормальной форме………………………………………………9

Описание  основных функций программы ………………………………………………………10

Текст программы…………………………………………………………………………………..13

Выводы по работе…………………………………………………………………………………20

Список  использованной литературы……………………………………………………………..21

 

      Задание кафедры 

     Написать  программу на языке СУБД, реализующей элементы языка SQL. Даны сущности, между которыми необходимо установить связь. Атрибуты сущностей задаются самостоятельно (3-6 на каждую сущность). При необходимости, добавление новых сущностей приветствуется. Программа должна иметь удобный интерфейс пользователя и корректно реализовывать основные операции (добавление, удаление, изменение, поиск записи по любому атрибуту, сортировку при выводе).

     Вариант № 7: Бухгалтерия предприятия. Сущности: поставщик, поставка, товар.

 

      Описание предметной области 

     Для начала разберемся с понятиями.

     Таблица - совокупность строк и столбцов. Почти полная аналогия с таблицами на бумаге. Важные уточнения: Каждый столбец должен иметь имя, уникальное в пределах этой таблицы. А строки, в теории баз данных, могут следовать в любом порядке, и не имеют номеров. Поэтому к каждой строке принято добавлять какой-нибудь идентификатор, для того, чтобы потом можно было легко найти ее.

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

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

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

     - уникальностью. В таблице нет  двух разных строк с одинаковыми  значениями в нашем потенциальном  ключе.

     - неизбыточностью. Нельзя убрать  один из столбцом из ключа, так, чтобы он не потерял уникальности.

     Рассмотрим, например, такую таблицу: 

     № паспорта Фамилия Имя Отчество Должность 

     123456 Иванов Иван Иванович Директор 

     234567 Петров Петр Иванович Его зам 

     345678 Сидорова Мария Ивановна Секретарша  

     В данной таблице в качестве потенциального ключа можно рассматривать любой столбец.

     Понятно, что отчество не может быть потенциальным  ключом - есть совпадения. Фамилия - может, если только мы не планируем появления  новых строк в таблице. Можно  взять комбинацию фамилии и должности, вряд ли у нас будет два директора-однофамильца. Номер паспорта также подходит на роль потенциального ключа. К каждой конкретной таблице потенциальных ключей может быть много. Выбор потенциального ключа - дело программиста. Тот же номер паспорта может не подойти, если мы ожидаем кого-нибудь с поддельным паспортом. Выбор делается каждый раз заново для каждой ситуации.

     Первичные ключи. Итак, с потенциальными ключами определились. Первичный ключ - это один из потенциальных ключей. Тот, который больше понравится. В реальной ситуации, новичок выберет номер паспорта. А что выберет профессионал? Профессионал добавит еще одно поле-счетчик, которое будет содержать уникальное для каждой записи значение. В Delphi такой тип поля называется AutoIncrement, в SQL Server есть целых 2 варианта - TimeStamp и свойтсво Identity поля.

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

     Внешние ключи. Когда мы создаем какую-нибудь базу данных, например для начисления зарплаты, нам не удобно всех работников упоминать в одной таблице. Если, например, какой-нибудь из них упоминается там не один раз (зарплата, премия, надбавки, снятия, налоги и пр.), то при изменении его/ее фамилии надо будет пробежаться по всем строкам, и поменять все вхождения. Это неудобно. Имеем две таблицы: 

     Код работника Вид движения Сумма 

     1   Оклад   100 

     1   Премия  30 

     1   Налоги  -25 

     2   Оклад   90 

     ... ... ... 

     Код работника Фимилия Имя Отчество 

     1   Иванов Иван Иванович 

     2   Петров Петр Иванович 

     3   Сидорова Мария Ивановна  

     В первой таблице - с деньгами - столбец "Код работника" называется внешним  ключом. Ясно, что он не может существовать без соответствующей строки из второй таблицы, в которой столбец "Код работника" - уже знакомый нам обычный первичный ключ. Вторая таблица - с фамилиями - является как бы "справочником фамилий" для первой.

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

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

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

     От  того, как продумывается структуры  данных будет многое зависеть. Это  касается программирования вообще, а  не только баз данных, но здесь это проявляется сильнее всего. И чем больше данных в базе, тем серьезнее надо отнестись к проработке ее структуры.

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

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

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

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

     Неделимость означает, что ваше поле не должно делиться на более мелкие. Например, речь идет о базе сотрудников для отдела кадров. Будет ли поле "Фамилия" неделимым? Ясно, что будет, куда его еще делить. А поле "ФИО"? Тут все зависит от контекста - если не предполагаеся использовать потом экзотические запросы типа "Выбрать всех Александровичей", то тоже можно считать его неделимым. А вот адрес лучше разделить на улицу, дом и квартиру, т.е. на 2 или 3 поля, тогда будет проще выбрать всех живущих на одной улице. Хотя, можете и его считать неделимым, если адрес - второстепенная информация. А вот с телефоном его объединять не стоит.

     Неповторяемость означает, что не повторяется значение полей от одного поля к другому. Имеется ввиду не та ситуация, когда указывается несколько полей с одинаковыми значениями. Например делается записная книжка. Какие поля туда внесencz? Фамилия, имя, телефон, e-mail... А может несколько телефонов? В наше время почти у каждого есть и рабочий, и домашний, и мобильный... А у некоторых может быть несколько рабочих или несколько мобильных номеров. Так сколько таких полей ввести? Правильнее всего будет создать еще одну таблицу с телефонами, а в первой только поместить ссылку на нее. Тогда можно будет для каждого указать произвольное число телефонов. 

     Код Фамилия Адрес.... 

     1 Иванов   

     2 Петров

             

     Чей Какой  Номер 

     1 Рабочий 1 23-45-67 

     1 Рабочий 2 23-45-98 

     1 Домашний 11-34-98 

     2 Домашний 45-09-87 

     ... ...  ...  

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

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

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

     Первый - если у нас накладные нумеруются каждый день начиная с первой, то номер не может однозначно определить накладную, и не может быть первичным  ключом. А номер вместе с датой - может. Можно поискать первичные ключи среди имеющихся полей (номер паспорта в базе сотрудников), а можно попытаться объединить несколько, пытаясь обеспечить уникальность.

     Очень простой вариант - создаем поле-счетчик  и указываем его в качестве первичного ключа.

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

     Есть  ведомость начисления зарплаты: 
 
 

     Таб № Фамилия Должность Сумма 

     1 Иванов Директор 100 

     2 Петров его зам 90  

     Поля "Фамилия" и "Должность" - лишние, потому, что мы эти данные можем  взять из таблицы для отдела кадров. То есть при печати эти поля будут, а вот в бази их хранить не следует.

     Считается что первых трех нормальных форм достаточно для большинства практических применений.

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

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

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

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

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

 

      Диаграмма «сущность-связь» 
 

 

     

     Нормализованные таблицы в 3 нормальной форме 

     Отношение находится в 3-ей нормальной форме  если оно находится во 3-ой нормальной форме и каждый ключевой атрибут  не транзитивно зависит от первичного ключа.

     Используя данное определение были получены и приведены к 3-ей нормальной форме следующие отношения-таблицы:

     
Индекс  поставщика Имя поставщика Адрес Телефон Факс E-mail
 
 

Таблица 1 
 

Таблица 2

Ключ  поставки Индекс поставки Код поставки Дата Цена поставки № склада
 

 

Ключ  товара Индекс товара Название товара Количество  товара Цена единицы  товара
 

Таблица 3 
 

     Из  приведенных таблиц видно что  первая таблица (поставщик) является главной  по отношению ко второй (поставка), в  свою очередь вторая таблица (поставка) является главной по отношению к третьей таблице (товар).

     Первая  таблица находится со второй в  отношении «одно ко многому».

     Вторая  таблица находится с третьей  в отношении «одно ко многому».

 

      Описание основных функций программы  

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

     Программа имеет интуитивно понятный интерфейс. При загрузки, программа имеет  следующий вид: 

       
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Рис. 1 

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

     При нажатии на вкладку «поиск» отображается Поисковая система информации (Рис 2).

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

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

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

       
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Рис. 2 

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

     При нажатии на вкладку «База данных»  открывается окно редактирования базы данных (Рис. 3).

     В этом окне можно отредактировать, удалить  или добавить запись. Здесь представлены 3 таблицы для редактирования: поставщик, поставка, товар. Редактирование таблиц производится с помощью кнопок, которые расположены над каждой таблицей.

     После редактирования вся информации заносится  в базу данных. 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

       
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Рис. 3

 

      Текст программы 

     unit Unit1; 

     interface 

     uses

       Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,

       Dialogs, Grids, DBGrids, ComCtrls, StdCtrls, ExtCtrls, DBCtrls, XPMan; 

     type

       TForm1 = class(TForm)

         PageControl1: TPageControl;

         TabSheet1: TTabSheet;

         PageControl2: TPageControl;

         TabSheet2: TTabSheet;

         TabSheet3: TTabSheet;

         TabSheet4: TTabSheet;

         DBGrid1: TDBGrid;

         Label1: TLabel;

         GroupBox1: TGroupBox;

         GroupBox2: TGroupBox;

         GroupBox3: TGroupBox;

         CheckBox1: TCheckBox;

         CheckBox2: TCheckBox;

         CheckBox3: TCheckBox;

         CheckBox4: TCheckBox;

         CheckBox5: TCheckBox;

         CheckBox6: TCheckBox;

         CheckBox7: TCheckBox;

         CheckBox8: TCheckBox;

         CheckBox9: TCheckBox;

         CheckBox10: TCheckBox;

         CheckBox11: TCheckBox;

         CheckBox12: TCheckBox;

         Edit1: TEdit;

         Edit2: TEdit;

         Edit3: TEdit;

         Edit4: TEdit;

         Edit5: TEdit;

         Edit6: TEdit;

         Edit7: TEdit;

         Edit8: TEdit;

         Edit9: TEdit;

         Edit10: TEdit;

         Edit11: TEdit;

         Edit12: TEdit;

         Button1: TButton;

         GroupBox4: TGroupBox;

         GroupBox5: TGroupBox;

         GroupBox6: TGroupBox;

         CheckBox13: TCheckBox;

         CheckBox14: TCheckBox;

         CheckBox15: TCheckBox;

         CheckBox16: TCheckBox;

         CheckBox17: TCheckBox;

        GroupBox7: TGroupBox;

         CheckBox18: TCheckBox;

         CheckBox19: TCheckBox;

         CheckBox20: TCheckBox;

         CheckBox21: TCheckBox;

         GroupBox8: TGroupBox;

         CheckBox22: TCheckBox;

         CheckBox23: TCheckBox;

         CheckBox24: TCheckBox;

         GroupBox9: TGroupBox;

         CheckBox25: TCheckBox;

         CheckBox26: TCheckBox;

         CheckBox27: TCheckBox;

         CheckBox28: TCheckBox;

         DBGrid2: TDBGrid;

         DBGrid3: TDBGrid;

         DBGrid4: TDBGrid;

         DBNavigator1: TDBNavigator;

         DBNavigator2: TDBNavigator;

         DBNavigator3: TDBNavigator;

         XPManifest1: TXPManifest;

         Button2: TButton;

         TabSheet5: TTabSheet;

         procedure FormActivate(Sender: TObject);

         procedure DBGrid1TitleClick(Column: TColumn);

         procedure CheckBox25Click(Sender: TObject);

         procedure CheckBox26Click(Sender: TObject);

         procedure CheckBox27Click(Sender: TObject);

         procedure CheckBox28Click(Sender: TObject);

         procedure Button1Click(Sender: TObject);

         procedure Button2Click(Sender: TObject);

       private

         { Private declarations }

       public

         { Public declarations }

       end; 

     var

       Form1: TForm1; 

     implementation 

     uses Unit2; 

     {$R *.dfm} 

     var

     nam:integer; 

     procedure viborpostavshik;

     begin

     with form1 do begin

     if CheckBox25.State=cbChecked then begin

     checkbox13.State:=cbchecked;

     checkbox14.State:=cbchecked;

     checkbox15.State:=cbchecked;

     checkbox16.State:=cbchecked;

     checkbox17.State:=cbchecked;

     end;

     if CheckBox25.State=cbUnchecked then begin

     checkbox13.State:=cbUnchecked;

     checkbox14.State:=cbUnchecked;

     checkbox15.State:=cbUnchecked;

     checkbox16.State:=cbUnchecked;

     checkbox17.State:=cbUnchecked;

     end;

     end;

     end; 

     procedure viborpostavka;

     begin

     with form1 do begin

     if CheckBox26.State=cbChecked then begin