Лучше ли делать меньше обращений к базе данных и выводить результаты в массиве? - PullRequest
0 голосов
/ 14 июня 2010

Я пытаюсь создать более лаконичный способ делать сотни вызовов в БД. Вместо того, чтобы выписывать весь запрос каждый раз, когда я хотел вывести одно поле, я пытался перенести код в класс, который выполнял весь запрос. Это класс у меня до сих пор:

class Listing {

/* Connect to the database */
private $mysql;

function __construct() {
    $this->mysql = new mysqli(DB_LOC, DB_USER, DB_PASS, DB) or die('Could not connect');
}
function getListingInfo($l_id = "", $category = "", $subcategory = "", $username = "", $status = "active") {
    $condition = "`status` = '$status'";
    if (!empty($l_id)) $condition .= "AND `L_ID` = '$l_id'";
    if (!empty($category)) $condition .= "AND `category` = '$category'";
    if (!empty($subcategory)) $condition .= "AND `subcategory` = '$subcategory'";
    if (!empty($username)) $condition .= "AND `username` = '$username'";
    $result = $this->mysql->query("SELECT * FROM listing WHERE $condition") or die('Error fetching values');
    $info = $result->fetch_object() or die('Could not create object');
    return $info;
}
}

Это облегчает доступ к любой информации, которую я хочу, из одной строки.

$listing = new Listing;
echo $listing->getListingInfo('','Books')->title;

Выводит заголовок первого листинга в категории «Книги». Но если я хочу вывести цену этого листинга, я должен сделать еще один вызов getListingInfo (). Это делает другой запрос к БД и снова возвращает только первую строку.

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

Ответы [ 4 ]

7 голосов
/ 14 июня 2010

У вас действительно есть проблемы с производительностью?

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

Такая абстракция доступа к БД, скорее всего, станет проблемой обслуживания и, вероятно, не повлияет на производительность.

Кроме того, вы подвержены SQL-инъекциям .

0 голосов
/ 14 июня 2010

Да, это будет вызывать БД слишком часто.

Пара решений

1) поместить информацию о листинге в переменную

2) кэшировать результаты в хэш-карте или словаре (будьте осторожны при утечках памяти)

0 голосов
/ 14 июня 2010

Вы должны иметь возможность сохранить весь объект из запроса в переменную и затем получить доступ к отдельным значениям из этого объекта:

$object = $listing->getListingInfo('','Books');
$title = $object->title;
$price= $object->price;

Но вы также можете использовать fetch_assoc () и вернуть весь вспомогательный массив:

$array = $listing->getListingInfo('','Books');
$title = $object['title'];
$price= $object['price'];

Это даст вам те же результаты, а также только один запрос к БД.

EDIT : если getListingInfo () является единственной функцией, вам следует подумать о следующем:

  1. переименуйте функцию в prepareListingInfo () и внутри функции только подготовьте запрос и сохраните его в переменной класса.
  2. добавить функцию getNextListingInfo (), которая будет возвращать объект или ассоциативный массив со следующей строкой.

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

0 голосов
/ 14 июня 2010

Либо кэшируйте результат во внутреннюю переменную

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

...