버전: v2.3.0
select
테이블에서 데이터를 조회합니다.
select($table, $columns)
table [string]
대상 테이블 이름입니다.
columns [array/string]
조회할 컬럼입니다.
select($table, $columns, $where)
table [string]
대상 테이블 이름입니다.
columns [array/string]
조회할 컬럼입니다.
where [array] (선택 사항)
결과를 좁히는 WHERE 조건입니다.
select($table, $join, $columns, $where)
table [string]
대상 테이블 이름입니다.
join [array]
관련 테이블을 조인하기 위한 JOIN 정의입니다. JOIN이 필요 없다면 생략할 수 있습니다.
columns [array/string]
조회할 컬럼입니다.
where [array] (선택 사항)
결과를 좁히는 WHERE 조건입니다.
반환값
[array] 조회 결과 배열입니다.
columns 매개변수에
*를 사용하면 모든 컬럼을 조회할 수 있지만, 성능과 가독성을 위해 필요한 컬럼만 명시적으로 지정하는 것이 좋습니다.$data = $database->select("account", [
"user_name",
"email"
], [
"user_id[>]" => 100
]);
// 예시 결과:
// array(
// [0] => array(
// "user_name" => "foo",
// "email" => "foo@bar.com"
// ),
// [1] => array(
// "user_name" => "cat",
// "email" => "cat@dog.com"
// )
// )
foreach ($data as $item) {
echo "사용자: " . $item["user_name"] . " - 이메일: " . $item["email"] . "<br/>";
}
// 모든 컬럼을 선택합니다.
$data = $database->select("account", "*");
// 하나의 컬럼만 선택합니다.
$data = $database->select("account", "user_name");
// 예시 결과:
// array(
// [0] => "foo",
// [1] => "cat"
// )
콜백으로 행 순차 처리하기
기본적으로
select()은 전체 결과 세트를 메모리에 로드하고 이를 배열로 반환합니다.많은 수의 행을 조회할 때는 메모리 사용량이 크게 늘어날 수 있습니다.
function ($data) {} 같은 콜백을 select()의 마지막 인수로 전달하면 Medoo는 전체 결과를 메모리에 저장하지 않고 각 행을 즉시 가져와 처리합니다.이 방식은 대규모 데이터 세트를 다룰 때 특히 더 메모리 효율적입니다.
$database->select("account", ["name"], function ($data) {
echo $data["name"];
});
$database->select("account", [
"name"
], function ($data) {
echo $data["name"];
});
성능 벤치마크
다음 예에서는 MySQL 데이터베이스에서 1,000개, 5,000개 및 20,000개의 행을 가져오고 출력할 때 메모리 사용량을 비교합니다. 메모리 사용량은
memory_get_usage()으로 측정됩니다.// 방법 1
$database->select("account", ["name"], function ($data) {
echo $data["name"];
});
// 비교:
// 방법 2
$data = $database->select("account", ["name"]);
foreach ($data as $item) {
echo $item["name"];
}
| 방법 1 | 방법 2 | |
| 1,000개 레코드 | 789KB | 1.2MB |
| 5,000개 레코드 | 1.1MB | 3.3MB |
| 20,000개 레코드 | 2.26MB | 11.1MB |
테이블 조인
SQL JOIN 절은 여러 테이블의 행을 결합합니다. Medoo는 조인을 간단하게 작성할 수 있는 구문을 제공합니다.
- [>] ==> LEFT JOIN
- [<] ==> RIGHT JOIN
- [<>] ==> FULL JOIN
- [><] ==> INNER JOIN
$database->select("post", [
// 기본 테이블과 조인할 테이블 사이의 관계를 정의합니다.
"[>]account" => ["author_id" => "user_id"]
], [
"post.title",
"account.city"
]);
post 테이블의 author_id 컬럼은 account 테이블의 user_id 컬럼과 연결됩니다."[>]account" => ["author_id" => "user_id"]
LEFT JOIN "account" ON "post"."author_id" = "account"."user_id"
두 테이블 모두 동일한 컬럼명을 사용하는 경우 단축 형식을 사용할 수 있습니다.
"[>]album" => "user_id"
LEFT JOIN "album" USING ("user_id")
여러 컬럼명이 두 테이블에서 동일하게 쓰인다면 이를 배열로 전달할 수 있습니다.
"[>]photo" => ["user_id", "avatar_id"]
LEFT JOIN "photo" USING ("user_id", "avatar_id")
동일한 테이블을 두 번 이상 조인해야 하는 경우 조인된 테이블에 별칭을 할당합니다.
"[>]account (replier)" => ["replier_id" => "user_id"]
LEFT JOIN "account" AS "replier" ON "post"."replier_id" = "replier"."user_id"
컬럼명 앞에 테이블 이름을 붙여 먼저 조인된 테이블을 참조할 수도 있습니다.
"[>]account" => ["author_id" => "user_id"], "[>]album" => ["account.user_id" => "user_id"]
LEFT JOIN "account" ON "post"."author_id" = "account"."user_id" LEFT JOIN "album" ON "account"."user_id" = "album"."user_id"
다중 JOIN 조건
"[>]account" => [ "author_id" => "user_id", "album.user_id" => "user_id" ]
LEFT JOIN "account" ON "post"."author_id" = "account"."user_id" AND "album"."user_id" = "account"."user_id"
추가 JOIN 조건
조인 절에 논리적 조건을 추가할 수도 있습니다.
"[>]comment" => [ "author_id" => "user_id", "AND" => [ "rate[>]" => 50 ] ]
LEFT JOIN "comment" ON "post"."author_id" = "comment"."user_id" AND "rate" > 50
Raw 객체로 조인하기
"[>]account" => Medoo::raw("ON <post.author_id> = <account.user_id>")
LEFT JOIN "account" ON "post"."author_id" = "account"."user_id"
데이터 매핑
반환되는 데이터 구조는 원하는 형태로 매핑할 수 있습니다. 매핑 키는 원래 컬럼명과 같을 필요가 없으며 중첩된 구조도 지원합니다.
$data = $database->select("post", [
"[>]account" => ["user_id"]
], [
"post.content",
"userData" => [
"account.user_id",
"account.email",
"meta" => [
"account.location",
"account.gender"
]
]
], [
"LIMIT" => [0, 2]
]);
echo json_encode($data);
[
{
"content": "Hello world!",
"userData": {
"user_id": "1",
"email": "foo@example.com",
"meta": {
"location": "New York",
"gender": "male"
}
}
},
{
"content": "Hey everyone",
"userData": {
"user_id": "2",
"email": "bar@example.com",
"meta": {
"location": "London",
"gender": "female"
}
}
}
]
인덱스 기반 매핑
컬럼 정의의 첫 번째 키로 컬럼명을 사용하면 해당 컬럼 값을 기준으로 결과가 인덱싱됩니다.
$data = $database->select("post", [
"user_id" => [
"nickname",
"location",
"email"
]
]);
{
"10": {
"nickname": "foo",
"location": "New York",
"email": "foo@example.com"
},
"12": {
"nickname": "bar",
"location": "New York",
"email": "bar@medoo.in"
}
}
데이터 유형 선언
선택한 컬럼의 출력 유형을 명시적으로 선언할 수 있습니다.
// 지원되는 데이터 유형: [String | Bool | Int | Number | Object | JSON]
// [String]은 모든 출력값의 기본 타입입니다.
// [Object]는 serialize()로 직렬화한 PHP 데이터를 unserialize()로 복원합니다.
// [JSON]은 유효한 JSON 데이터를 json_decode()로 디코딩합니다.
$data = $database->select("post", [
"[>]account" => ["user_id"]
], [
"post.post_id",
"profile" => [
"account.age [Int]",
"account.is_locked [Bool]",
"account.userData [JSON]"
]
]);
echo json_encode($data);
[
{
"post_id": "1",
"profile": {
"age": 20,
"is_locked": true,
"userData": ["foo", "bar", "tim"]
}
},
{
"post_id": "2",
"profile": {
"age": 25,
"is_locked": false,
"userData": ["mydata1", "mydata2"]
}
}
]
// 객체를 데이터베이스에 저장한 뒤 나중에 다시 가져옵니다.
class Foo {
var $bar = "cat";
public function __wakeup()
{
$this->bar = "dog";
}
}
$object_data = new Foo();
$database->insert("account", [
"data" => $object_data
]);
$data = $database->select("account", [
"data [Object]"
]);
echo $data[0]["data"]->bar;
// unserialize() 과정에서 객체의 __wakeup() 메서드가 호출됩니다.
// 따라서 출력 결과는 "dog" 입니다.
별칭
컬럼명이나 테이블명에 별칭을 지정할 수 있습니다. 조인 쿼리에서 이름 충돌을 피하거나 결과를 더 분명하게 보여 주고 싶을 때 특히 유용합니다.
$data = $database->select("account", [
"user_id",
"nickname (my_nickname)"
]);
// 예시 결과:
// array(
// [0] => array(
// "user_id" => "1",
// "my_nickname" => "foo"
// ),
// [1] => array(
// "user_id" => "2",
// "my_nickname" => "bar"
// )
// )
$data = $database->select("post (content)", [
"[>]account (user)" => "user_id",
], [
"content.user_id (author_id)",
"user.user_id"
]);
// 예시 결과:
// array(
// [0] => array(
// "author_id" => "1",
// "user_id" => "321"
// ),
// [1] => array(
// "author_id" => "2",
// "user_id" => "322"
// )
// )
SELECT
"content"."user_id" AS "author_id",
"user"."user_id"
FROM
"post" AS "content"
LEFT JOIN "account" AS "user" USING ("user_id")
DISTINCT
선택한 컬럼에
DISTINCT 키워드를 추가하려면 컬럼명 앞에 @을 붙이세요.$data = $database->select("account", [
// 이 컬럼에 DISTINCT 가 적용됩니다.
"@location",
"id",
"name",
]);
SELECT DISTINCT "location", "id", "name" FROM "account"
고유 값을 계산하려면 Raw 표현식을 사용하세요.
$data = $database->select("account", [
"unique_locations" => Medoo::raw("COUNT(DISTINCT <location>)")
]);
SELECT COUNT(DISTINCT "location") AS "unique_locations" FROM "account"