2015-12-06 2 views
0

У меня есть следующие DBиспользовать один или несколько запросов запросов к БД PosgreSQL

CREATE TABLE IF NOT EXISTS users (
    user_uid INTEGER PRIMARY KEY, 
    user_name CHAR(64) NOT NULL, 
    token_id INTEGER 
); 

CREATE TABLE IF NOT EXISTS unique_thing (
    id SERIAL PRIMARY KEY, 
    unique_thing_id INTEGER NOT NULL, 
    option_id INTEGER NOT NULL 
); 

CREATE TABLE IF NOT EXISTS example (
    id SERIAL PRIMARY KEY, 
    variable INTEGER NOT NULL, 
    variable_2 INTEGER NOT NULL, 
    char_var CHAR(64) NOT NULL, 
    char_var2 CHAR(512), 
    char_var3 CHAR(256), 
    file_path CHAR(256) NOT NULL 
); 



CREATE TABLE IF NOT EXISTS different_option_of_things (
    id SERIAL PRIMARY KEY, 
    name CHAR(64) 
); 

CREATE TABLE IF NOT EXISTS commits (
    id SERIAL PRIMARY KEY, 
    user_id INTEGER NOT NULL, 
    unique_thing_id INTEGER NOT NULL, 
    value REAL NOT NULL, 
    var CHAR(512) NOT NULL, 
    example_id INTEGER NOT NULL, 
    boolean_var boolean NOT NULL 
); 

Таблицы unique_thing, different_option_of_things и examples будут статическими (данные будут добавлены редко и вручную). Таблица commits будет довольно большой. Это будет таблица только для вставки (я удалю очень редко). Пользователь будет таблицей с идентификацией пользователя. Он будет не таким большим, как unique_thing, но у него будет довольно много пользователей.

Данные таблицы будет выглядеть следующим образом:

INSERT INTO users VALUES(1, 'pacefist', 2); 
INSERT INTO users VALUES(3, 'motherfucker', 4); 
INSERT INTO users VALUES(4, 'cheater', 5); 

INSERT INTO different_option_of_things VALUES(1, 'blablab'); 
INSERT INTO different_option_of_things VALUES(2, 'smth different'); 
INSERT INTO different_option_of_things VALUES(3, 'unique_thing'); 
INSERT INTO different_option_of_things VALUES(4 ,'unique_thing2'); 

INSERT INTO unique_thing VALUES(DEFAULT, 1, 1); 
INSERT INTO unique_thing VALUES(DEFAULT, 1, 3); 
INSERT INTO unique_thing VALUES(DEFAULT, 2, 3); 
INSERT INTO unique_thing VALUES(DEFAULT, 2, 2); 

INSERT INTO example VALUES(1, 20, 20, 'fsdfsdf', 'fgdfgdfg', 'url', '/home/user/file.txt'); 
INSERT INTO example VALUES(2, 24, 40, 'sfadfadf', 'dfgdfg', 'url', '/home/user/file2.txt'); 

INSERT INTO commits VALUES(DEFAULT, 1, 1, 55.43, '1234567', 1, TRUE); 
INSERT INTO commits VALUES(DEFAULT, 2, 1, 97.85, '1234573', 2, TRUE); 
INSERT INTO commits VALUES(DEFAULT, 3, 1, 0.001, '98766543', 1, TRUE); 
INSERT INTO commits VALUES(DEFAULT, 4, 2, 100500.00, 'xxxxxxxx', 1, TRUE); 

Таким образом, данные будут вставлены Ther следующим образом:

1) I have input data of different_option_of_things, e.g., [ blablab, unique_thing], the REAL value (like 8.9999) and the number of example like `fsdfsdf` 
2) It's necessary to find this record in the table `unique_thing` 
a) if we've found 2 or more values or haven't found anything 
    results false -> the search is over 
b) if we've found 1 result then 
    3) we are searching all values (record from unique_thing) in the 'commits' table. 
    a) if it has been found 
     a.1 search of the given example name 
      a.1.1 if found -> get first 25 values and check whether the current value is bigger 
       a.1.1.1 if yes, we make a commit 
       a.1.1.2 if no, do nothing (do not duplicate the value) 
      a.1.2 no -> no results 
     a.2 if no -> no results 

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

Вопрос: лучше ли создавать 3 функции вместо одного большого запроса?

SELECT count(1) AS counter FROM different_option_of_things 
     WHERE name IN (SELECT * FROM unnest(different_option_of_things)); 

SELECT * FROM example where id=fsdfsdf; 

SELECT TOP 25 
    FROM commits 
    JOIN unique_thing 
    ON commits.id=unique_thing.unique_thing_id where value > 8.9999; 

if results-> 0 do a commit 

Или лучше написать один огромный запрос? Я использую Postgresql, Tornado и momoko.

+0

Есть несколько ограничений внешнего ключа, отсутствующих в вашем DDL, так что кажется. – wildplasser

+0

Я бы рекомендовал хранимые процедуры, каждый для получения и установки данных - логика зависит только от данных db. От momoko будет только один вызов (выполнить) – kwarunek

+0

, так лучше ли звонить одному или нескольким? Я могу создать его, но я беспокоюсь о производительности –

ответ

0

Я бы предпочел, чтобы две хранимые процедуры каждый получали и вставляли данные.

Плюсы:

  • все необходимые данные в БД, так что это похоже на работу для дб,
  • каждый вызов на выполнение необходимо:

    1. ГЭТ/ждать доступен соединение в пуле (в зависимости от вашего приложения)
    2. запрос на запуск
    3. выборка данных
    4. Разъемное соединение

      x. А между всей этой операции на IOLoop

    Хотя Момоко неблокирующая, это не для свободного

  • дб может быть апи, не только мешок данных

Против:

  • логика в дБ означает, что вы зависите от нее - измените двигатель db (для пример для cassandra) будет сложнее
  • Часто логика в db означает, что тестов нет. Конечно, вы можете, и вы должны его протестировать (например,pgTap)
  • для простых задач это кажется излишним

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

Смежные вопросы