Сбор данных из базы данных


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

Примечание:

ДБ() очень похож на ПДО(), он просто расширяет его, добавляя несколько функций я не использую здесь.

Должность::addExtra() добавить реферат данных разработка базы данных.

Например, он создал $данных[13] = $данных['от бд1'] .' с '. $данных['из DB2']. Это потому что они собираются быть переданы в шаблон.

$db = new Db();
$s = new Session();

# Default statement and parameters
$stmt = 
"SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
    (
        SELECT COUNT(*)
            FROM Flags as f 
                JOIN Posts as p1
                ON p1.PostPID = f.FlagPID
            WHERE p1.PostPID = p.PostPID
    ) as PostFlags
    FROM Posts AS p
        JOIN Users AS u
        ON p.PostUID = u.UserUID
    ORDER BY PostTime DESC
    LIMIT 0, 30";
$par = array();

# We change the statement if the tab is selected
if ($tab = get('tab')) {
    switch ($tab) {
        case 'admin':
            $stmt = 
            "SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
            (
                SELECT COUNT(*)
                    FROM Flags as f 
                        JOIN Posts as p1
                        ON p1.PostPID = f.FlagPID
                    WHERE p1.PostPID = p.PostPID
            ) as PostFlags
                FROM Posts AS p
                    JOIN Users AS u
                    ON p.PostUID = u.UserUID
                WHERE p.PostUID = 1
                ORDER BY PostTime DESC
                LIMIT 0, 30";
            break;
        case 'trusted':
            if ($s->isLogged()) {
                $stmt = 
                "SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
                (
                    SELECT COUNT(*)
                        FROM Flags as f 
                            JOIN Posts as p1
                            ON p1.PostPID = f.FlagPID
                        WHERE p1.PostPID = p.PostPID
                ) as PostFlags
                    FROM Posts AS p
                        JOIN Users AS u
                        ON p.PostUID = u.UserUID
                    WHERE p.PostUID IN (
                        SELECT TrustedUID
                        FROM Trust
                        WHERE TrusterUID = :uid
                    )
                    ORDER BY PostTime DESC
                    LIMIT 0, 30";
                $par = array('uid' => $s->getUID());
            } else {
                $stmt = '';
            }
            break;
        case 'favorite':
            if ($s->isLogged()) {
                $stmt = 
                "SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
                (
                    SELECT COUNT(*)
                        FROM Flags as f 
                            JOIN Posts as p1
                            ON p1.PostPID = f.FlagPID
                        WHERE p1.PostPID = p.PostPID
                ) as PostFlags
                    FROM Posts AS p
                        JOIN Users AS u
                        ON p.PostUID = u.UserUID
                    WHERE p.PostPID IN (
                        SELECT FavoritePID
                        FROM Favorites
                        WHERE FavoriteUID = :uid
                    )
                    ORDER BY PostTime DESC
                    LIMIT 0, 30";
                $par = array('uid' => $s->getUID());
            } else {
                $stmt = '';
            }
            break;
        case 'top':
            $weekAgo = time() - week;
            $monthAgo = time() - month;
            $stmt = 
            "SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
            (
                SELECT COUNT(*)
                    FROM Flags as f 
                        JOIN Posts as p1
                        ON p1.PostPID = f.FlagPID
                    WHERE p1.PostPID = p.PostPID
            ) as PostFlags
                FROM Posts AS p
                    JOIN Users AS u
                    ON p.PostUID = u.UserUID
                WHERE p.PostTime > $monthAgo
                LIMIT 0, 3
            UNION
            SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime, u.UserUID, u.UserName, u.UserImage, u.UserRep,
            (
                SELECT COUNT(*)
                    FROM Flags as f 
                        JOIN Posts as p1
                        ON p1.PostPID = f.FlagPID
                    WHERE p1.PostPID = p.PostPID
            ) as PostFlags
                FROM Posts AS p
                    JOIN Users AS u
                    ON p.PostUID = u.UserUID
                WHERE p.PostTime > $weekAgo
                ORDER BY PostFlags DESC
                LIMIT 0, 30";
            break;
        case 'recent':
        default:
            break;
    }
} 

# Loading posts
try {
    $sql = $db->prepare($stmt);
    $sql->execute($par);
    $posts['Data'] = $sql->fetchAll();
} catch (PDOException $e) {
    throw new MyEx($e->getMessage());
}

if (count($posts['Data']) > 0) {
    foreach ($posts['Data'] as &$post) {
        $post = Post::addExtra($post);
    }
}


400
5
задан 24 марта 2011 в 01:03 Источник Поделиться
Комментарии
2 ответа

Общие связанных с SQL совет: я бы фактор большинство из этих запросов в один вид, затем вы можете добавить больше параметров при выборе из поля зрения. Вы также можете удалить несколько экземпляров переменной, разложения изнутри запросов, и заменить их именованными параметрами по всей территории (у вас :жидкости уже).

Например:

CREATE OR REPLACE VIEW PostsAnnotated AS
SELECT p.PostPID, p.PostUID, p.PostText, p.PostTime,
u.UserUID, u.UserName, u.UserImage, u.UserRep,
(
SELECT COUNT(*)
FROM Flags as f
JOIN Posts as p1
ON p1.PostPID = f.FlagPID
WHERE p1.PostPID = p.PostPID
) as PostFlags
FROM Posts AS p
JOIN Users AS u
ON p.PostUID = u.UserUID
ORDER BY PostTime DESC;

SELECT FROM PostsAnnotated WHERE PostUID = 1 LIMIT 30;
SELECT FROM PostsAnnotated WHERE PostUID IN (
SELECT TrustedUID
FROM Trust
WHERE TrusterUID = :uid)
LIMIT 30;

Насколько код вокруг addExtra: я не намерян $посты['данных'] немедленно заменить его. Вместо этого я бы петли на SQL результаты и добавить до $посты['данных'] (МСИО синтаксис $посты['данных'][] = $next_elem).

4
ответ дан 25 марта 2011 в 08:03 Источник Поделиться

Похоже, что единственная разница между этими запросами заключается в предложении where. Если это так, вы можете очистить код немного убрав лишние по SQL, например:


$параметр stmt =
"Выберите P.PostPID, стр. PostUID, стр. PostText, стр. PostTime, у.UserUID, у.Имя пользователя, у.UserImage, у.UserRep,
(
ВЫБЕРИТЕ ФУНКЦИИ COUNT(*)
С флагами как F
Присоединяйтесь к должности Р1
На Р1.PostPID = Ф.FlagPID
Где Р1.PostPID = Р.PostPID
) как PostFlags
От должности п
Присоединиться к пользователям, как у
На стр. PostUID = у.UserUID";

если (вкладка $ = вам (вкладка'')) {
переключатель (вкладка$) {

//...СНиП...
дело "доверенных":
если ($с->isLogged()) {
$параметр stmt = $stmt задано .
"Где P.PostUID в (
Выберите TrustedUID
От доверия
Где TrusterUID = :Уид
)";
$пар = массив('идентификатор uid' => $ь->getUID());
} еще {
$параметр stmt = ";
}
перерыв;
//...СНиП...

}
}

$полу . "Приказ по PostFlags деск лимит 0, 30";

Это улучшает читабельность немного, а только те части, которые меняются от запроса к присутствуют.

2
ответ дан 24 марта 2011 в 10:03 Источник Поделиться