mysqli 또는 PDO-장단점은 무엇입니까? [닫은]


342

대신 우리는 준비된 명령문과 트랜잭션 지원과 같은 것들을 위해 mysqli와 PDO를 사용하는 것으로 나뉩니다. 일부 프로젝트는 하나를 사용하고 다른 프로젝트는 하나를 사용합니다. 우리가 다른 RDBMS로 옮길 가능성은 거의 없습니다.

PDO가 준비된 명령문에 대해 명명 된 매개 변수를 허용한다는 한 가지 이유 때문에 PDO를 선호하며 mysqli가 인식하지 못하는 한 PDO를 선호합니다.

하나의 접근 방식을 사용하기 위해 프로젝트를 통합 할 때 표준으로 다른 것을 선택하는 데 다른 장단점이 있습니까?


5
기사 는 사용할 것을 선택하는 데 도움 이 될 것입니다. 성능을 고려 하면 선택하는 데 도움 될 수 있습니다.
ravi404

3
얼마나 많은 사람들이 "건설적이지 않은"질문에 찬성하고 별표를 표시했는지는 재밌습니다. 문제는 전체 스레드가 매우 건설적이라는 것입니다. 중재자가 질문이 건설적인지 여부를 판단 할 때 이것을 고려해야합니다.
marlar

@ marlar 나는 sooooooo에 동의합니다! 이것은 실제로 StackOverflow에서 가장 큰 문제입니다. 훌륭한 질문 / 토론은 항상 종료됩니다.
Sliq

답변:


243

글쎄, 당신은 객체 지향적 측면, 준비된 진술, 그것이 표준이된다는 사실 등으로 논쟁 할 수 있습니다. 그러나 나는 대부분 누군가를 살인자 기능으로 더 잘 설득한다는 것을 알고 있습니다. 그래서 거기 있습니다 :

PDO의 좋은 점은 데이터를 가져 와서 객체에 자동으로 주입 할 수 있다는 것입니다. ORM 을 사용하고 싶지 않지만 (단순한 스크립트이기 때문에) 객체 매핑을 좋아한다면 정말 멋집니다 :

class Student {

    public $id;
    public $first_name;
    public $last_name

    public function getFullName() {
        return $this->first_name.' '.$this->last_name
    }
}

try 
{
    $dbh = new PDO("mysql:host=$hostname;dbname=school", $username, $password)

    $stmt = $dbh->query("SELECT * FROM students");

    /* MAGIC HAPPENS HERE */

    $stmt->setFetchMode(PDO::FETCH_INTO, new Student);


    foreach($stmt as $student)
    {
        echo $student->getFullName().'<br />';
    } 

    $dbh = null;
}
catch(PDOException $e)
{
    echo $e->getMessage();
}

12
위와의 차이점이 $mysqliResult->fetch_object("student");있습니까?
Andy Fleming

2
@ e-satis 아니오, PHP를 사용합니다. 그래서 공공 필드는 캡슐화를 위반 AS A BEST PRACTICE는 그냥 롤 : 공공 필드를 사용하지 구글 않습니다 만 액세서 ... : google-styleguide.googlecode.com/svn/trunk/...를 .
OZ_

6
@ e-satis : 뛰어 들어서 죄송하지만 변수가 변경 될 때 발생하는 일을 제어하려면 게터와 세터가 필요합니다. 그렇지 않으면 객체의 내부 상태를 간단하게 보장 할 수 없습니다 (특히 내부에 다른 객체가있는 경우 문제가 됨). 이것은 전적으로 언어와 무관합니다. @OZ_ : 진정하세요. 개인적인 비판은 다른 사람을 수비에만 두게 할 것입니다.
James P.

2
@monadic : 동의합니다. 캡슐화는 물론 핵심 구성 요소 나 복잡한 객체 등을 다룰 때 유효한 인수이지만, 그렇지 않으면 읽기 / 쓰기 관련 레코드 일 수 있습니다. 배열은 허용됩니다. 또한 레코드가 시스템을 통해 플로팅되므로 유형을보다 쉽게 ​​확인할 수 있습니다.
Dan Lugg

15
@ outis 나는 소수에 있지 않기를 희망하지만, 새로운 개발자에 대한 그들의 안전에 대한 답변을 판단해야한다고 생각하지 않습니다. 거칠게 들리지만 사실입니다. SO에 대한 답변의 목적은 복사하여 붙여 넣기 코드를 제공하는 것이 아니라 이해를 제공하는 것입니다. 모든 보안상의 허점이나 패턴 결함이 예제에서 다루어 지도록하는 것은 응답자의 일이 아닙니다. 직면 해 봅시다. 코드가 복사되는 애플리케이션은 본질적으로 동일한 코드를 사용하는 다른 애플리케이션과 다릅니다.
Mattygabe

57

한 데이터베이스에서 다른 데이터베이스로 애플리케이션을 이동하는 것은 흔하지 않지만 조만간 다른 RDBMS를 사용하여 다른 프로젝트에서 작업하는 것을 발견 할 수 있습니다. PDO를 가지고 집에 있다면 그 시점에서 배우는 것이 최소한 한 가지는 없을 것입니다.

그 외에도 PDO API가 조금 더 직관적이며 객체 지향적 인 느낌이 듭니다. mysqli는 그것이 의미하는 바를 알면 객체화 된 절차 적 API 인 것처럼 느낍니다. 요컨대, PDO로 작업하기가 더 쉽지만 물론 주관적입니다.


25

내 의견으로는 진술 지원이 더 좋기 때문에 PDO를 사용하기 시작했다. ActiveRecord-esque 데이터 액세스 계층을 사용하고 있으며 동적으로 생성 된 명령문을 구현하는 것이 훨씬 쉽습니다. MySQLi의 매개 변수 바인딩은 단일 함수 / 메소드 호출에서 수행해야하므로 런타임까지 바인딩 할 매개 변수의 수를 알지 못하면 선택에 사용해야합니다 call_user_func_array()(적절한 기능 이름이라고 생각합니다) . 간단한 동적 결과 바인딩은 잊어 버리십시오.

무엇보다도 PDO는 매우 합리적인 수준의 추상화이기 때문에 PDO를 좋아합니다. SQL을 작성하고 싶지 않은 완전 추상 시스템에서 쉽게 사용할 수 있지만보다 최적화 된 순수한 쿼리 유형의 시스템을 사용하거나이 둘을 혼합하여 일치시킬 수 있습니다.


2
동적으로 생성 된 쿼리와 결과 바인딩이 가능합니다. 애플리케이션에서 수행합니다. 그러나 그것은 큰 고통입니다.
Pim Jager

17

PDO가 표준이며, 대부분의 개발자가 사용할 것으로 예상됩니다. mysqli는 본질적으로 특정 문제에 대한 맞춤형 솔루션이지만 다른 DBMS 관련 라이브러리의 모든 문제가 있습니다. PDO는 모든 노력과 영리한 사고가 갈 곳입니다.


15

명심해야 할 것이있다 : 현재 (PHP 5.2) PDO 라이브러리는 버그가있다 . 이상한 버그로 가득합니다. 예를 들어 : PDOStatement변수에 변수 를 저장하기 전에 변수는 unset()많은 버그를 피해야합니다. 이들 대부분은 PHP 5.3에서 수정되었으며 2009 년 초 PHP 5.3에서 릴리스되어 다른 버그가있을 수 있습니다. 안정적인 릴리스를 원하면 PHP 6.1 용 PDO를 사용하고 커뮤니티를 돕기 위해서는 PHP 5.3 용 PDO를 사용하는 데 중점을 두어야합니다.


2
PDO가 제공하는 이익은 버그를 이해하고 해결할 가치가 있다고 생각합니다. PHP 자체는 매우 가혹한 버그로 가득 차 있으며, 일부는 효율적으로 해결할 수도 없지만 다른 옵션 대신에 사용할 수있는 많은 이점을 제공합니다.
Brian Warshaw

11
음, 이상하게도 PDO에 어떤 버그도 경험하지 못했습니다. 그리고 나는 그것을 많이 사용합니다.
NikiC

Mysqli에도 버그가 있습니다. 모든 소프트웨어에는 버그가 있습니다.
Bill Karwin

10

PDO에 대한 또 다른 주목할만한 차이점은 PDO::quote()메소드가 자동으로 따옴표를 추가하지만 mysqli::real_escape_string()(및 유사한)는 그렇지 않다는 것입니다.

PDO :: quote ()는 입력 문자열을 따옴표로 묶고 (필요한 경우) 기본 드라이버에 적합한 따옴표 스타일을 사용하여 입력 문자열 내에서 특수 문자를 이스케이프합니다.


8

PDO는 매일 데이터베이스에로드를 분배하기 위해 마스터 및 슬레이브 연결을 설정할 수 있으므로 사이트 / 웹 앱이 실제로 확장되는 경우 훨씬 쉽게 확장 할 수 있으며, PHP는 표준으로 PDO로 이동하고 있습니다.

PDO 정보

웹 응용 프로그램 확장


6

실행 속도 측면에서 MySQLi가이기는하지만 MySQLi를 사용하여 좋은 래퍼가 없으면 준비된 명령문을 다루는 기능이 끔찍합니다.

여전히 버그가 있지만 누군가가 원한다면 여기 있습니다 .

간단히 말해, 속도 향상을 원한다면 MySQLi; 사용 편의성을 원한다면 PDO.


2
속도와 관련하여 벤치 마크를 제공 할 수 있습니까?
Julius F

8
Jonathen Robson은 jonathanrobson.me/2010/06/mysqli-vs-pdo-benchmarks 에서 두 가지를 적절히 비교했습니다 . 요약 : inserts-거의 동일, selects-mysqli는 준비되지 않은 명령문의 경우 ~ 2.5 % 더 빠르며, 준비된 명령문의 경우 6.7 % 빠릅니다. 성능 저하가 얼마나 작은 지 고려할 때, 사용의 기능과 유연성은 PDO일반적으로 성능 저하보다 중요합니다.
Adam

1
@Adam 내 블로그에 연결해 주셔서 감사합니다!
jnrbsn

@ daemonfire300 사실입니다. 벤치 마크가 필요 없습니다. PDO는 mysqli 라이브러리를 래핑합니다. 누군가 PDO가 mysqli보다 빠르다는 것을 증명할 수 있다면 팬을 때릴 것입니다. :-D
Dyin

@jnrbsn 아담의 말에 동의하십니까?
Basit

5

개인적으로 PDO를 사용하지만 주로 선호도의 문제라고 생각합니다.

PDO에는 다시 SQL 주입 ( 준비된 명령문 ) 을 돕는 몇 가지 기능이 있지만, SQL에주의를 기울이면 mysqli에서도이를 달성 할 수 있습니다.

다른 데이터베이스로 이동한다고해서 PDO를 사용해야하는 것은 아닙니다. "특수 SQL 기능"을 사용하지 않는 한 한 DB에서 다른 DB로 전환 할 수 있습니다. 그러나 예를 들어 "SELECT ... LIMIT 1"을 사용하자마자 "SELECT TOP 1 ..."인 MS-SQL로 이동할 수 없습니다. 그래서 이것은 어쨌든 문제가됩니다.


22
MySQLi는 진술을 준비했다.
Tower

5

수정 된 답변.

이 두 API에 대해 어느 정도 경험을 쌓은 후 네이티브 준비된 명령문으로 mysqli를 사용할 수 없게 만드는 2 개의 차단 레벨 기능이 있다고 말할 수 있습니다.
그들은 이미 2 가지 훌륭한 (아직 과소 평가 된) 답변에서 언급되었습니다.

  1. 임의의 수의 자리 표시 자에 값 바인딩
  2. 단순한 배열로 데이터 반환

( 이 답변 에도 언급되어 있음 )

어떤 이유로 mysqli는 둘 다 실패했습니다.
요즘에는 두 번째 기능 ( get_result ) 이 약간 향상 되었지만 mysqlnd 설치에서만 작동하므로 스크립트 에서이 기능에 의존 할 수 없습니다.

그러나 오늘날까지도 가치에 의한 구속력은 없습니다.

따라서 PDO 는 하나만 선택할 수 있습니다.

와 같은 다른 모든 이유

  • 명명 된 자리 표시 자 (이 구문 설탕은 과대 평가됨)
  • 다른 데이터베이스 지원 (아무도 사용하지 않은 사람)
  • 객체로 가져 오기 (사용할 수없는 구문 설탕)
  • 속도 차이 (없음)

중요하지 않습니다.

동시에이 두 API에는 다음 과 같은 실제 중요한 기능 이 부족 합니다 .

  • 식별자 자리 표시 자
  • 동적 바인딩을 덜 수월하게 만드는 복잡한 데이터 유형의 자리 표시 자
  • 더 짧은 애플리케이션 코드.

따라서 실제 요구 사항을 충족하려면 이러한 API 중 하나를 기반으로 수동으로 구문 분석 된 자리 표시자를 구현하는 자체 추상화 라이브러리를 만들어야합니다. 이 경우 mysqli를 선호합니다. 추상화 수준이 낮기 때문입니다.


마지막으로 삶의 사실을 알고 거부하지 않는 누군가 ...
Ihsan

4

벤치 마크 스크립트 에서 각 방법은 10000 번 테스트되고 각 방법의 총 시간 차이가 인쇄됩니다. 당신은 당신의 자신의 구성에 이것을해야합니다, 나는 결과가 다를 것이라고 확신합니다!

이것들은 내 결과입니다 :

  • " SELECT NULL" -> PGO()빨리 ~ 0.35 초에 의해
  • " SHOW TABLE STATUS" -> mysqli()빨리 ~ 2.3 초에 의해
  • " SELECT * FROM users" -> mysqli()~ 33 초 빨라짐

참고 : mysqli에 대해-> fetch_row ()를 사용하면 열 이름이 배열에 추가되지 않으므로 PGO에서 그렇게 할 수있는 방법을 찾지 못했습니다. 그러나-> fetch_array ()를 사용하더라도 mysqli는 약간 느리지 만 여전히 PGO보다 빠릅니다 (SELECT NULL 제외).


17
PGO 란 무엇입니까? 그리고 33 초 더 빠릅니다 ! 나는 그것을 믿기 힘들다 ...
Alix Axel

3

PDO의 MySQLi가 내가 정말로 좋아하지 않는 한 가지는 PDO의 결과를 지정된 클래스 유형의 객체 (예 :)로 반환 할 수 있다는 것 $pdo->fetchObject('MyClass')입니다. MySQLi fetch_object()stdClass객체 만 반환 합니다.


19
실제로, 클래스를 수동으로 지정할 수 있습니다 : "object mysqli_result :: fetch_object ([string $ class_name [, array $ params]])". stdClass는 아무것도 지정하지 않은 경우에만 사용됩니다.
Andrioid

-4

명심해야 할 것이 하나 있습니다.

Mysqli는 열 이름을 나타내는 키가있는 열을 반환하는 fetch_assoc () 함수를 지원하지 않습니다. 물론 그렇게하기 위해 자신의 함수를 작성하는 것도 가능합니다. 그리 오래 걸리지는 않았지만 실제로 작성하는 데 어려움을 겪었습니다 . t 속임수 :))


4
매뉴얼을 보셨습니까? php.net/manual/en/mysqli-result.fetch-assoc.php

2
오래 전에 구현했지만 예 매뉴얼을 확인했습니다. 준비된 진술과 함께 작동합니까? 의심합니다.
mike

2
실제로, 그것은 부분적으로 호기심이 있습니다. 일반 쿼리에서는 배열을 가져올 수 있지만 매개 변수화 된 쿼리에서는 배열을 가져올 수 없습니다.
Álvaro González

1
왜 틀린 답을 삭제하지 않겠습니까?
Majid Fouladpour

2
@MajidFouladpour – 대답은 분명히 틀리지 않습니다 . 컨텍스트가 누락되었습니다. Mysqli는 연관 배열 검색을 완전히 지원 하지 않습니다 .
Álvaro González
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.