НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ “ЛЬВІВСЬКА ПОЛІТЕХНІКА”
ІНСТИТУТ КОМП'ЮТЕРНИХ НАУК ТА ІНФОРМАЦІЙНИХ ТЕХНОЛОГІЙ
/
Кафедра САПР
З В І Т
до лабораторної роботи №3
з курсу: “Організація Баз Даних та знань”
Львів 2016
ТЕМА РОБОТИ
Індексно-послідовний метод доступу до файлів на зовнішніх запам’ятовуючих пристроях
МЕТА РОБОТИ
Оглянути органiзацiю i ведення файлiв iндексно-послiдовного доступу; набути практичнi навички у програмуваннi алгоритмiв iндексно-послiдовного доступу до файлiв на зовнiшнiх запам'ятовуючих пристроях.
ІНДИВІДУАЛЬНЕ ЗАВДАННЯ
Створити базу даних, для підтримки бази даних на тему «Риболовний Магазин», яка реалізовує наступні функції:
1.Створення файлу бази даних.
2.Друк бази даних.
3.Читання запису, за вказаним ключем.
4.Пошук за вказаним полем (до 3-х полів).
5.Вставка запису.
6.Видалення запису.
7.Модифікація запису.
8.Захист від переповнення
ТЕОРЕТИЧНІ ВІДОМОСТІ
Якщо файл впорядкований по ключах, то звичайно для адресацiї використовується таблиця, що називається iндексом. При звертаннi до таблицi задається ключ шуканого запису, а результатом процедури пошуку у таблицi є вiдносна адреса запису у зовнiшнiй пам'ятi.Якщо для адресацiї файла використовується iндекс, ЕОМ в основному здiйснює пошук в iндексi, а не у файлi даних. При цьому суттєво економиться час, але потребується пам'ять для зберiгання iндексу.Існує багато iндексних методiв доступу, в основi яких лежить принцип створення окремого iндексного файла. індексний файл значно менший вiд власне бази даних, i, оскiльки вiн може повнiстю зберiгатися в оперативнiй пам'ятi, швидкодiя пошуку у ньому значно вища.В iндексно-послiдовному методi доступу iндексний файл завжди впорядкований за так званим первинним ключем (головний атрибут фiзичного запису).Оскiльки у цьому методi i записи файла даних впорядкованi за ключем, iндекс звичайно мiстить не посилання на окремий запис, а посилання на блоки записiв, всерединi яких можна здiйснювати пошук i сканування. Збереження посилань на блоки записiв, а не на окремi записи значно зменшує розмiр iндексу. Наприклад, якщо в блоцi зберiгається 10 записiв, то для нього в iндексному файлi буде одна стаття, а не 10, i розмiр iндексного файла зменшується в 10 разiв.
ТЕКСТ ПРОГРАМИ
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace Laba3_indexBD
{
class Program
{
static string path = "default.txt";
static string second = "second.txt";
const int MAX_ZAP = 5;
static bool rivnist = false; // логічні змінні - викор при введення існуючого ключа
static bool povtor = false; // ця також
static void Main(string[] args)
{
Console.WindowHeight = 40;
Console.WindowWidth = 190;
Console.WriteLine("/////////////////////////////////////////////////////////////////////////////////////////////////");
Console.WriteLine("/ Лабораторна робота №3 //");
Console.WriteLine("/ Предметна область: Ресторан //");
Console.WriteLine("/ Виконав: студент КН-25 Омелян Дмитро //");
Console.WriteLine("/////////////////////////////////////////////////////////////////////////////////////////////////");
menu();
Console.ReadLine();
}
static void menu()
{
bool doit = true;
while (doit)
{
Console.WriteLine("\n=============================================================================================================================================================================================");
Console.WriteLine("Введiть номер команди \n1. Створення БД \n2. Друк БД \n3. Вставка запису \n4. Модифiкацiя записуч \n5. Видалення запису \n6. Читання запису за вказаним ключем \n7. Пошук запису \n8. Показ вмiсту айдi-файлу \n9. Заверршення роботи з програмою");
int file_v = menu_vvid();
Console.WriteLine("=============================================================================================================================================================================================");
switch (file_v)
{
case 1:
creating();
break;
case 2:
show_zap();
break;
case 3:
{
Console.WriteLine("Введіть запис що бажаєте додати ");
add_zap(vvid_zapusy());
}
break;
case 4:
{
Console.WriteLine("Введіть запис що бажаєте модифікувати ");
mod_zap(vvid_zapusy());
}
break;
case 5:
vud_zap();
break;
case 6:
find_id();
break;
case 7:
find_zap();
break;
case 8:
show_id();
break;
case 9:
doit = false;
break;
default:
{
Console.WriteLine("Неправильно введена команда, введіть ще раз");
}
break;
}
}
}
static int menu_vvid()
{
try
{
int v = Int32.Parse(Console.ReadLine());
return v;
}
catch (FormatException)
{
return menu_vvid();
}
}
static void enter(string zapus, string way)
{
using (StreamWriter sw = new StreamWriter(way, true, System.Text.Encoding.Default))
{
sw.WriteLine(zapus);
}
}
static string vvid_zapusy()
{
Console.Write("Введіть id ");
string riadok = Console.ReadLine() + " ";
Console.Write("Введіть поставщика - ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть страву - ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть кількість порцій - ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть чи наявна страва (y/n) - ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть дату приготування - ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть розділ - ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть Вагу - ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть цiну- ");
riadok += Console.ReadLine() + " ";
Console.Write("Введіть рейтинг - ");
riadok += Console.ReadLine() + " ";
Console.WriteLine();
return riadok;
}
////////////////////АЙДІ-ФАЙЛ////////////////////////////
static void change_id(string str)
{
string[] zap = str.Split(' ');
if (File.Exists("id" + path) == false)
{
enter(zap[0] + " 1_" + path, "id" + path);
enter(str, "1_" + path);
}
else
{
string[] mas = File.ReadAllLines("id" + path);
int max = 0;
for (int i = 0; i < mas.Length; i++)
{
string[] m_id = mas[i].Split(' ');
string[] ch_id = m_id[1].Split('_');
int x = Int32.Parse(ch_id[0]);
if (max < x) max = x;
}
max++;
enter_id(zap[0] + " " + max + "_" + path, "id" + path);
enter(str, max + "_" + path);
}
}
static void corect_id(string str_id, string name_way)
{
string[] mas = File.ReadAllLines("id" + path);
for (int i = 0; i < mas.Length; i++)
{
string[] stx = mas[i].Split(' ');
if (stx[1] == name_way)
{
mas[i] = str_id + " " + name_way;
}
}
for (int i = 0; i < mas.Length; i++)
enter(mas[i], second);
File.Delete("id" + path);
File.Move(second, "id" + path);
}
// змінити запис в айді-файлі
static void impruve_id(string str, string path_id)
{
string[] zap = str.Split(' ');
string[] id_mas = File.ReadAllLines("id" + path);
for (int i = 0; i < id_mas.Length; i++)
{
string[] id_str = id_mas[i].Split(' ');
if (id_str[1] == path_id)
{
int x1 = Int32.Parse(zap[0]);
int y1 = Int32.Parse(id_str[0]);
if (x1 < y1) corect_id(zap[0], id_str[1]);
}
}
}
// показ вмісту айді файлу
static void show_id()
{
string[] mas = File.ReadAllLines("id" + path);
Console.WriteLine(" ____________________________________");
Console.WriteLine("| Номер запису| \t Назва блоку |");
for (int i = 0; i < mas.Length; i++)
{
string[] stx = mas[i].Split(' ');
Console.WriteLine("|\t" + stx[0] + "\t|\t" + stx[1] + "|");
}
Console.WriteLine("|____________________________________|");
}
static void del_id(string str)
{
string[] mas = File.ReadAllLines("id" + path);
int j = 0;
bool b = false;
for (int i = 0; i < mas.Length; i++)
{
string[] stx = mas[i].Split(' ');
if (str == stx[1])
{
j = i;
b = true;
}
}
if (b)
{
File.Delete("id" + path);
for (int i = 0; i < mas.Length; i++)
if (j != i) enter(mas[i], "id" + path);
}
}
////////////////////СТВОРЕННЯ БАЗИ ДАНИХ//////////////////
static void creating()
{
Console.WriteLine("Введіть назву файлу (якщо БД(файл) було створено до того, то вона буде відкрита, у протилежному випадку буде створено нову БД)");
path = Console.ReadLine() + ".txt";
}
////////////////////ДОДАВАННЯ ЗАПИСУ/////////////////////
static void add_zap(string str)
{
if (File.Exists("id" + path) == false)
{
change_id(str);
}
else
{
rivnist = false;
povtor = false;
string[] zap = str.Split(' ');
bool b = false;
int x = Int32.Parse(zap[0]);
int j = 0;
string[] id = File.ReadAllLines("id" + path);
for (int i = id.Length - 1; i >= 0; i--)
{
string[] m_id = id[i].Split(' ');
int y = Int32.Parse(m_id[0]);
if (x >= y)
{
b = vvid_id(str, m_id[1]);
j = i;
break;
}
if (i == 0 && x < y)
{
b = vvid_id(str, m_id[1]);
j = i;
}
}
if (b == false)
{
if (j != id.Length - 1)
{
string[] m_id = id[j].Split(' ');
string[] m_id_l = id[j + 1].Split(' ');
string[] mas_l = File.ReadAllLines(m_id_l[1]);
if (mas_l.Length < MAX_ZAP)
{
string stx = ret_enter(str, m_id[1]);
enter_id(stx, m_id_l[1]);
}
else
{
string stx = ret_enter(str, m_id[1]);
change_id(stx);
}
}
else
if (j == id.Length - 1)
{
string[] m_id = id[j].Split(' ');
string stx = ret_enter(str, m_id[1]);
change_id(stx);
}
}
}
}
// перевіряє на заповненість блок і заповнює його при не заповненому - поветртає true
static bool vvid_id(string str, string way)
{
string[] mas = File.ReadAllLines(way);
if (mas.Length >= MAX_ZAP)
{
return false;
}
enter_id(str, way);
return true;
}
// безпосереднє введення запису в блок
static void enter_id(string str, string path_id)
{
string[] zap = str.Split(' ');
int x = Int32.Parse(zap[0]);
impruve_id(str, path_id);
string[] mas = File.ReadAllLines(path_id);
{
bool b = true;
int i = 0;
while (i < mas.Length)
{
string[] stx = mas[i].Split(' ');
int y = Int32.Parse(stx[0]);
if (x == y)
{
if (povtor == false)
{
Console.Write("Даний запис уже існує, модифікувати його ? (Y/N)");
string v = Console.ReadLine();
if (v == "y" || v == "Y") rivnist = true;
povtor = true;
}
Console.WriteLine(rivnist);
if (rivnist) enter(str, second);
else enter(mas[i], second);
b = false;
i++;
}
else if (x < y && b == true)
{
enter(str, second);
b = false;
}
else if (x != y)
{
enter(mas[i], second);
i++;
}
}
if (b == true)
{
enter(str, second);
}
File.Delete(path_id);
File.Move(second, path_id);
}
}
// безпосереднє введення запису в блок і повернення останнього запису з блоку
static string ret_enter(string str, string way)
{
string[] mas = File.ReadAllLines(way);
impruve_id(str, way);
string[] zap = str.Split(' ');
int x = Int32.Parse(zap[0]);
string[] m = mas[mas.Length - 1].Split(' ');
int y1 = Int32.Parse(m[0]);
if (x > y1)
return str;
else
{
bool b = true;
int i = 0;
int z = 0;
while (z < MAX_ZAP)
{
string[] stx = mas[i].Split(' ');
int y = Int32.Parse(stx[0]);
if (x == y)
{
if (povtor == false)
{
Console.Write("Даний запис уже існує, модифікувати його ? (Y/N)");
string v = Console.ReadLine();
if (v == "y" || v == "Y") rivnist = true;
povtor = true;
}
if (rivnist) enter(str, second);
else enter(mas[i], second);
b = false;
i++;
z++;
}
else if (x < y && b == true)
{
enter(str, second);
b = false;
z++;
}
if (x != y)
{
enter(mas[i], second);
i++;
z++;
}
}
File.Delete(way);
File.Move(second, way);
return mas[mas.Length - 1];
}
}
////////////////////ВИВІД ЗАПИСІВ/////////////////////
static void show_zap()
{
if (File.Exists("id" + path) == false)
{
Console.WriteLine("Ще не внесено ніяких записів у базу даних, тому і не можливо вивести її записи, будь ласка, введіть перше записи");
return;
}
Console.WriteLine(" № \t Назва поставщика \t страва \t кількість порцій \t Наявність \t дата приготування \t розділ \t Вага \t Вартість \t Рейтинг ");
Console.WriteLine("запису \t \t \t \t \t \t \t \t \t ");
string[] id_mas = File.ReadAllLines("id" + path);
for (int i = 0; i < id_mas.Length; i++)
{
Console.WriteLine("=============================================================================================================================================================================================");
string[] id = id_mas[i].Split(' ');
string[] mas = File.ReadAllLines(id[1]);
for (int j = 0; j < mas.Length; j++)
{
string[] str = mas[j].Split(' ');
Console.WriteLine(str[0] + "\t " + str[1] + "\t " + str[2] + "\t " + str[3] + "\t\t " + str[4] + "\t " + str[5] + "\t " + str[6] + "\t\t " + str[7] + "\t\t" + str[8] + "\t\t " + str[9] + "\t\t" + id[1]);
}
}
Console.WriteLine("=============================================================================================================================================================================================");
}
////////////////////МОДИФІКАЦІЯ ЗАПИСУ/////////////////////
static void mod_zap(string str)
{
string[] zap = str.Split(' ');
int x = Int32.Parse(zap[0]);
bool b = false;
string[] id = File.ReadAllLines("id" + path);
for (int i = id.Length - 1; i >= 0; i--)
{
string[] m_id = id[i].Split(' ');
int y = Int32.Parse(m_id[0]);
if (x >= y)
{
b = mod_id(str, m_id[1]);
break;
}
}
if (b == false)
{
Console.Write("Даного запису не знайдено, добавити його ? ");
string v = Console.ReadLine();
if (v == "y" || v == "Y") add_zap(str);
}
}
static bool mod_id(string str, string way)
{
string[] zap = str.Split(' ');
int x = Int32.Parse(zap[0]);
string[] mas = File.ReadAllLines(way);
for (int i = 0; i < mas.Length; i++)
{
string[] stx = mas[i].Split(' ');
int y = Int32.Parse(stx[0]);
if (x == y)
{
mas[i] = str;
File.Delete(way);
for (int j = 0; j < mas.Length; j++)
enter(mas[j], way);
return true;
}
}
return false;
}
////////////////////ПОШУК ЗАПИСІВ/////////////////////
static void find_id()
{
Console.WriteLine("Введіть номер шуканого запису ");
string str = Console.ReadLine();
Console.WriteLine("Результати пошуку:\n");
find_block(str, 0);
}
static void find_zap()
{
Console.WriteLine("=============================================================================================================================================================================================");
Console.WriteLine("Введіть команду \n 1. пошук запису за цiною \n 2. пошук запису за назвою фірми ");
int x = Int32.Parse(Console.ReadLine());
Console.WriteLine("=============================================================================================================================================================================================");
switch (x)
{
case 1:
{
Console.WriteLine("Введіть шукану вартість");
string str = Console.ReadLine();
Console.WriteLine("Результати пошуку:\n");
find_block(str, 8);
}
break;
case 2:
{
Console.WriteLine("Введіть шукану фірму ");
string str = Console.ReadLine();
Console.WriteLine("Результати пошуку:\n");
find_block(str, 1);
}
break;
default: break;
}
}
static void find_block(string str_f, int x)
{
string[] id_mas = File.ReadAllLines("id" + path);
bool b = false;
for (int j = 0; j < id_mas.Length; j++)
{
string[] id_m = id_mas[j].Split(' ');
string[] mas = File.ReadAllLines(id_m[1]);
for (int i = 0; i < mas.Length; i++)
{
string[] str = mas[i].Split(' ');
if (str_f == str[x])
{
Console.WriteLine(str[0] + "\t " + str[1] + "\t " + str[2] + "\t " + str[3] + "\t\t " + str[4] + "\t " + str[5] + "\t " + str[6] + "\t\t " + str[7] + "\t\t" + str[8] + "\t\t " + str[9] + "\t\t" + id_m[1]);
b = true;
}
}
}
if (b == false) Console.WriteLine("Запису не знайдено");
}
////////////////////ВИВДАЛЕННЯ ЗАПИСУ/////////////////////
static void vud_zap()
{
Console.WriteLine("Введіть номер запису, що ви бажаєте видалити ");
string str = Console.ReadLine();
int x = Int32.Parse(str);
string[] id_mas = File.ReadAllLines("id" + path);
for (int i = id_mas.Length - 1; i >= 0; i--)
{
string[] id_zap = id_mas[i].Split(' ');
int y = Int32.Parse(id_zap[0]);
if (x >= y)
{
vud_blok(str, id_zap[1]);
return;
}
}
}
static void vud_blok(string str, string way)
{
string[] mas = File.ReadAllLines(way);
int j = 0;
bool b = false;
for (int i = 0; i < mas.Length; i++)
{
string[] stx = mas[i].Split(' ');
if (str == stx[0])
{
j = i;
b = true;
}
}
if (b)
{
if (mas.Length == 1)
{
File.Delete(way);
del_id(way);
}
else
{
if (j == 0)
{
string[] stx = mas[1].Split(' ');
corect_id(stx[0], way);
}
File.Delete(way);
for (int i = 0; i < mas.Length; i++)
if (j != i) enter(mas[i], way);
}
}
else Console.WriteLine("Запису не знайдено, тому і не видалено");
}
}
}
/
ВИСНОВКИ
На даній лабораторній роботі, я навчився створювати базу даних, побудовану на принципі iндексно-послідовний метод доступу до файлів на зовнішніх запам’ятовуючих пристроях, а саме, за допомогою методу хешування. Створивши свою хеш-функцію, я отримав можливість доступу до окремих блоків, відповідно, це значно пришвидшує пошук, вставку, видалення і модифікацію.При виконанні даної лаботироної великих глобальних помилок припущено не було.Правда було тяжко виконати і реалізувати певні функції.