Russian Qt Forum

Qt => Базы данных => Тема начата: Astrologer от Октябрь 04, 2010, 18:56



Название: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 04, 2010, 18:56
Всем привет. Передо мной стоит задача организовать БД, количество полей около 100, причем логически их скомпоновать достаточно сложно, потому что они никак не связаны. Также в дальнейшем понадобится сложная фильтрация, формирование отчетов. Как будет лучше - сделать по табличке с внешними ключами на каждый параметр, или одну таблицу в которой все и будет?  :)


Название: Re: Вопрос по организации структуры БД
Отправлено: vipet от Октябрь 04, 2010, 19:56
Если упоминается "кол-во полей", то как минимум они должны быть связаны тем, что могут/должны быть объединены с помощью понятия "запись" :)

Постановка задачи не очень ясна, но предполагаю, что может помочь такое:

1. Таблица Types
ID - PK
TypeName

2. Records
ID - PK
RecordName
...


Если для каждой записи должно присутствовать максимум одно значение типа, то
3.1. Таблица Values
RecordID - FK Records.ID
TypeID - FK Types.ID
PK = RecordID, TypeID

Если для каждой записи может присутствовать любое кол-во значений типов, то
3.2. Таблица Values
ID - PK
RecordID - FK Records.ID
TypeID - FK Types.ID

(PK = Primary Key, FK = Foreign Key)

Если надо еще один уровень, то выше т-цы Types заводим т-цу MetaTypes :)


Название: Re: Вопрос по организации структуры БД
Отправлено: ufna от Октябрь 04, 2010, 20:30
если БД реляционная, посмотри понятие "нормальная форма". Надо привести к третьей и будет тебе гуд.


Название: Re: Вопрос по организации структуры БД
Отправлено: Denjs от Октябрь 05, 2010, 02:32
если БД реляционная, посмотри понятие "нормальная форма". Надо привести к третьей и будет тебе гуд.
+1.
Автору изучать что такое нормальная форма (http://ru.wikipedia.org/wiki/%D0%9D%D0%BE%D1%80%D0%BC%D0%B0%D0%BB%D1%8C%D0%BD%D0%B0%D1%8F_%D1%84%D0%BE%D1%80%D0%BC%D0%B0)

или рассказать о предметной области, описать подробнее данные (что же таки планируется хранить в БД) и перечислить примеры планируемых запросов к БД.


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 05, 2010, 10:12
Есть набор файлов (dbf и txt в котором хранятся пары "значение-ключ"). После чтения файлов получаются пары "ключ-значение". Именно такие пары и планируется хранить в таблице. Запросы - самые разнообразные - выборки произвольных полей с фильтром по произвольному/ым полю/ям по критериям больше, меньше и т.д. В дальнейшем поля могут добавляться.

Например:
Код:
     
AMP1M = 1652.90
ANG_H = Azim
ANG_V = 49.6
ANT_REZ = 0.0
APERT1 = 3805 8 0.000084
APERT2 = 11313 8 0.000028
AZ1 = 67.05
AZ2 = 68.30
BOARD = LEFT
BORDER = 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000 0.00000000                                  
Таких полей - около 100 штук. Группировать их логически, как я упомянул - довольно проблематично. То есть нужно создавать 100 таблиц типа?:

Таблица baseTable
LastTimeModified - PK, bigint
Name - varchar

Таблица AMP1M
ID - PK,
F_KEY = FK baseTable.LastTimeModified
value - varchar

Таблица ANG_V
ID - PK,
F_KEY = FK baseTable.LastTimeModified
value - float

Таблица ANG_H
ID - PK,
F_KEY = FK baseTable.LastTimeModified
value - varchar
........

Таблица values
AMP1MID - FK AMP1m.ID
ANG_VID - FK ANG_V.ID
......
PK = ?
................


Название: Re: Вопрос по организации структуры БД
Отправлено: CroCIV от Октябрь 05, 2010, 10:29
таблица одна.
одна запись в ней соответствует одному файлу
столбцы в таблице = ключи.
с типами только надо будет проанализировать какие бывают вообще типы значений по данному ключу, и ссно где можно ставить инт/флоат/дата - там ставить инт/флоат/дату, где нельзя - там варчар переменной длинны, или блоб, если совсем все плохо. З.Ы.: ну т.е. используешь типы той СУБД с которой работаешь. Если ключ может содержать и/или текст и/или число и/или еще всякую лабуду, то придется к этому полю привязывать будет транскриптор на одном из уровней твоей системы...


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 05, 2010, 11:15
таблица одна.
одна запись в ней соответствует одному файлу
столбцы в таблице = ключи.

Какие ключи? На каждый столбец по первичному ключу?


Название: Re: Вопрос по организации структуры БД
Отправлено: CroCIV от Октябрь 05, 2010, 12:11
нет =)))

вот пример:

файл1
...
ANG_V = 49.6
ANT_REZ = 0.0
APERT1 = 3805 8 0.000084
APERT2 = 11313 8 0.000028
...

таблица
id  |name   |...|ANG_V|ANT_REZ|APERT1            |APERT2              |
1   |файл1 |...|49.6   |0.0        |3805 8 0.000084|11313 8 0.000028|


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 05, 2010, 12:22
Аа.. Ну я так и делал. Просто раньше писал в разные таблицы, по каждой таблице на файл.


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 05, 2010, 13:43
Такой вопрос возник:
Если так, то все хорошо отображается. Но стоит раскомментить dbs.close() - и прога вылетает. Как будто не успевает отработать транзакции.
Код:
void QDbfReader::openDBF(QString dbfName)
{
QSqlDatabase dbs = QSqlDatabase::addDatabase("QIBASE");
    dbs.setDatabaseName("c:\\database.fdb");
    dbs.setUserName("sysdba");
    dbs.setPassword("masterkey");
    QStringList dbList = QSqlDatabase::drivers();
    bool _is_open= dbs.open();
    QStringList tList = dbs.tables();
    QSqlQuery statement(dbs);
    QString error;
    QString createQuery;
    if (!tList.contains("baseTable", Qt::CaseInsensitive))
    {
        QMapIterator<QString, QString> iterator(allFields);
        createQuery = "create table basetable ( p_key bigint NOT NULL PRIMARY KEY, dbfName varchar(50), ";
        while(iterator.hasNext())
        {
            iterator.next();
            createQuery+= "\"" + iterator.key() + "\"" +  " varchar(100), ";
        }
        createQuery.replace(createQuery.lastIndexOf(","), 1, ")");
        dbs.transaction();
        statement.exec(createQuery);
        error = statement.lastError().text();
        dbs.commit();
    }

    if (!tList.contains("fieldsTable", Qt::CaseInsensitive))
    {
        createQuery = "create table fieldsItems ( ";
        QMapIterator<QString, QString> iterator(allFields);
        while(iterator.hasNext())
        {
            iterator.next();
            createQuery+= "\"" + iterator.key() + "\"" +  " varchar(50), ";
        }
        createQuery.replace(createQuery.lastIndexOf(","), 1, ")");
        dbs.transaction();
        statement.exec(createQuery);
        error = statement.lastError().text();
        dbs.commit();
    }

    //insertion
    QString insertionQuery = "INSERT INTO baseTable (p_key, dbfName, ";
    QMapIterator<QString, QString> iterator(allFields);
    while(iterator.hasNext())
    {
        iterator.next();
        insertionQuery+= "\"" + iterator.key() + "\", ";
    }
    insertionQuery.replace(insertionQuery.lastIndexOf(","), 2, ") ");
    insertionQuery+= "VALUES (" + p_key + ", '" + dateInfo.baseName() + "', ";
    iterator.toFront();
    while(iterator.hasNext())
    {
        iterator.next();
        insertionQuery+= "'" + iterator.value() + "'" +  ", ";
    }
    insertionQuery.replace(insertionQuery.lastIndexOf(","), 2, ") ");
    query_to_file(insertionQuery);
    dbs.transaction();
    statement.exec(insertionQuery);
    error = statement.lastError().text();
    dbs.commit();

    file.close();

    //dbs.close();
}



Название: Re: Вопрос по организации структуры БД
Отправлено: crossly от Октябрь 05, 2010, 13:59
а что это query_to_file ??


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 05, 2010, 14:06
Да просто сохранялка в текстовый файл.
Код:
void QDbfReader::query_to_file (QString query)
{
    QFile file_stream("d:\\dbf\\out.txt");
    QTextStream stream(&file_stream);
    file_stream.open(QFile::WriteOnly);
    stream << query;
    file_stream.close();
}


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 05, 2010, 19:54
Какие нибудь идеи по поводу транзакций и dbs.close()? :)


Название: Re: Вопрос по организации структуры БД
Отправлено: MoPDoBoPoT от Октябрь 05, 2010, 20:18
Попробуй освободить все занятые ресурсы для этого соединения (очистить объекты QSqlQuery с помощью метода QSqlQuery::clear()).


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 06, 2010, 08:56
Что в моем случае более целесообразно - одна таблица с кучей полей или куча таблиц с одним полем? В случае с одной таблицей и кучей полей какой первичный ключ выбрать?


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 06, 2010, 16:16
1. Таблица Types
ID - PK
TypeName

2. Records
ID - PK
RecordName
...
Если для каждой записи должно присутствовать максимум одно значение типа, то
3.1. Таблица Values
RecordID - FK Records.ID
TypeID - FK Types.ID
PK = RecordID, TypeID

Если 100 таблиц, то вторичных ключей в таблице Values будет 100?


Название: Re: Вопрос по организации структуры БД
Отправлено: Pretorean от Октябрь 06, 2010, 20:56
В случае с одной таблицей и кучей полей какой первичный ключ выбрать?

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


Название: Re: Вопрос по организации структуры БД
Отправлено: CroCIV от Октябрь 12, 2010, 10:21
1. Таблица Types
ID - PK
TypeName

2. Records
ID - PK
RecordName
...

Если для каждой записи должно присутствовать максимум одно значение типа, то
3.1. Таблица Values
RecordID - FK Records.ID
TypeID - FK Types.ID
PK = RecordID, TypeID
А мне таки не понятно в чем хранить значения различных типов? все бросать в поле BLOB? Тогда как выполнять поиск по значению потом?
хотя.....
если у таблицы Values будет набор всех типов полей типа дата, число, число с плавающей, текст и т.п... то... ну еще написав логику составления запросов в связке таблица 2 тип такой - значит брать значение из таблицы Значений поля 4 (текс) .... то поиск по контенту организовать можно


Название: Re: Вопрос по организации структуры БД
Отправлено: Astrologer от Октябрь 20, 2010, 12:12
Просто хотят балалайку. Чтобы и так и эдак. Изначально это были таблицы. А времени на разработку ТЗ, типизации полей никто не дает. Вот поэтому приходится извращаться.


Название: Re: Вопрос по организации структуры БД
Отправлено: CroCIV от Ноябрь 01, 2010, 08:58
О, кстати, В MS SQL оказывается тип данных есть sql_variant. Это, конечно, ни разу не стандартный тип, но если мелкомягкую СУБД юзаешь, то можно использовать его для хранения значений.
...
Тип sql_variant можно использовать в столбцах, параметрах, переменных и возвращаемых значениях пользовательских функций. С помощью типа sql_variant эти объекты базы данных могут поддерживать значения других типов данных.

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