Vad betyder "tillräckligt komplett uppsättning SQL"? Nåväl, nu är det klart varför sqlite är hemskt, eftersom det inte har en global cache.


  • SQLite
  • Webbplatsutveckling
  • Jag bestämde mig till slut för att skriva en artikel om SQLite, där jag vill sammanfatta min 3-åriga erfarenhet av att använda denna databas under Windows. Jag ser att ämnet är populärt, men det finns lite information.

    En liten introduktion.

    Den här artikeln är inte för nybörjare.
    Det är inte en SQL-tutorial.
    Hon förespråkar inte att använda SQLite.
    Hon förespråkar inte att inte använda SQLite.
    Artikeln är skriven i form av frågor från en hypotetisk nybörjare till SQLite och svar på dem (eftersom det finns mycket information och det är åtminstone lite lättare att strukturera det så här).

    Vad är SQLite?
    SQLite är en inbäddad plattformsoberoende databas som stöder ett brett utbud av hela uppsättningen SQL-kommandon och är tillgänglig i källkod (på C-språk).

    Källkoder SQLite är allmän egendom, det vill säga det finns inga begränsningar för användning alls.

    Webbplats (med utmärkt dokumentation på engelska): http://sqlite.org

    Aktuell version: 3.7.13

    Du kan kompilera SQLite själv, men jag laddar ner den redan kompilerad i som Windows DLL.

    För egen montering brukar man ladda ner den sk. "sammanslagning"
    de där. SQLite-källor i form av en enda fil i C + sqlite3.h.

    För att minska storleken på SQlite-kod genom att eliminera onödiga saker, används alla möjliga DEFINEs.

    Hur populär är SQLite?
    Kortfattat: hon är överallt. Åtminstone på vilken smartphone som helst.
    Hur pålitlig är den?
    Mycket. När en version släpps går den igenom en serie seriösa automatiserade tester (~ 2 miljoner tester utförs), kodtäckning av tester är 100 % (sedan augusti 2009).
    Vilka andra verktyg tillhandahåller utvecklarna?
    Ett konsolverktyg för att arbeta med databaser är tillgängligt (sqlite3.exe, "ett kommandoradsskal för åtkomst till och modifiering av SQLite-databaser").
    Det är allt?
    Ja, allt från huvudutvecklarna. Däremot skriver andra människor alla möjliga chefer osv.
    Personligen har jag aldrig hittat den perfekta och använder konsolen.
    Vad betyder "tillräckligt komplett uppsättning SQL"?
    Som ni vet, i sin utveckling skyndade SQL till olika sidor. Stora tillverkare De började trycka in alla möjliga förlängningar. Och även om alla typer av standarder accepteras (SQL 92), i verkliga livet alla stora databaser stöder inte standarderna helt + de har något eget. Så, SQLite försöker leva efter principen om "minimal men komplett uppsättning". Det stöder inte komplicerade saker, men det är i stort sett samma som SQL 92.
    Och den introducerar några av sina egna funktioner, som är mycket bekväma, men inte standard.
    Vad exakt är i SQL-stöd kan det skapa förvirring?
    Du kan inte ta bort eller ändra en kolumn i en tabell (ALTER TABLE DROP COLUMN..., ALTER TABLE ALTER COLUMN...).
    Det finns triggers, men inte lika kraftfulla som de för stora RDBMS.
    Det finns stöd för främmande nyckel, men som standard är det INAKTIVERAD.
    Det finns inget inbyggt stöd för UNICODE (men det är i allmänhet inte svårt att uppnå).
    Inga lagrade procedurer.
    Vad är bra eller ovanligt?
    a) Varje post innehåller en virtuell rad-kolumn, som är lika med ett 64-bitars nummer (unik för tabellen).
    Du kan deklarera din kolumn INTEGER PRIMARY KEY och då kommer denna kolumn att bli rowid (med sitt eget namn, namnet rowid fungerar fortfarande).
    När du infogar en post kan du ange en rad, eller så kan du inte ange den (och systemet kommer då att infoga en unik).
    Detaljer: www.sqlite.org/autoinc.html
    b) du kan enkelt organisera databasen i minnet (detta är väldigt bekvämt och jag ska berätta mer om det lite senare);
    c) lätt att transportera: som standard är databasen en fil (i ett plattformsoberoende format);
    d) kolumntypen bestämmer inte vilken typ av värde som lagras i detta postfält, det vill säga vilket värde som helst kan matas in i vilken kolumn som helst;
    e) många inbyggda funktioner (som kan användas i SQL): www.sqlite.org/lang_corefunc.html;
    Jag förstår inte - vad är det för fel på typen? Varför behöver man en kolumntyp då överhuvudtaget?
    Kolumntypen avgör hur värdena jämförs (de måste konverteras till en enda typ när man jämför t.ex. inuti ett index).
    Men det tvingar dig inte att ange värden av denna typ i kolumnen. Något som svag skrivning.

    Låt oss säga att vi deklarerade en kolumn som "ETT HELTAL".
    SQlite låter dig ange värden av vilken typ som helst i denna kolumn (999, "abc", "123", 678.525).
    Om värdet som infogas inte är ett heltal, försöker SQlite att casta det till ett heltal.
    De där. strängen "123" kommer att förvandlas till heltal 123, och de återstående värdena kommer att skrivas "som de är".

    Så är det möjligt att inte specificera kolumntypen alls?
    Detta görs väldigt ofta: SKAPA BORD foo (a,b,c,d).
    Hur är det med arkitekturen? Finns det ingen server?
    Det finns ingen server, själva applikationen är en server. Tillgång till databasen sker genom "anslutningar" till databasen (något liknande ett OS-filhandtag), som vi öppnar genom ett anrop till motsvarande DLL-funktion. Vid öppning anges namnet på databasfilen. Om det inte finns något sådant skapas det automatiskt.
    Det är acceptabelt att öppna flera anslutningar till samma databas (via ett filnamn) i samma eller olika applikationer.
    Systemet använder blockeringsmekanismer för filåtkomst på OS-nivå för att få det hela att fungera
    (dessa mekanismer fungerar vanligtvis inte bra på nätverksenheter, så det rekommenderas inte att använda SQlite med en fil på nätverket).
    Till en början arbetade SQlite efter principen "många läser, en skriver."
    Det vill säga bara en anslutning skriver till databasen i det här ögonblicket tid. Om andra anslutningar försöker skriva också, kommer de att få SQLITE_BUSY-felet.
    Du kan dock ange en tidsgräns för operationen. Då kommer anslutningen, inför en upptagen databas, att vänta N sekunder innan den misslyckas med felet SQLITE_BUSY.
    Så vad ska vi göra?
    Antingen en anslutning och alla förfrågningar genom den, eller fortsätt från en möjlig timeout och se till att SQL-körningen upprepas.
    Det finns en annan möjlighet: inte så länge sedan den nya sorten SQLite-logg: Write Ahead Log, WAL .
    Om du aktiverar just detta loggläge för databasen, kommer flera anslutningar att kunna modifiera databasen samtidigt.
    Men i detta läge upptar databasen redan flera filer.
    Nåväl, nu är det klart varför SQLite är hemskt, eftersom det inte har en GLOBAL CACHE?
    Alla moderna RDBMS är faktiskt otänkbara utan en global delad cache, som kan lagra alla möjliga godsaker som kompilerade parametriserade frågor. Detta görs av en server som inte finns här. Men inom samma applikation kan SQlite dela cachen mellan flera anslutningar (läs här: www.sqlite.org/sharedcache.html) och spara lite minne.
    Varför klagar alla på att SQLite är långsam?
    Två skäl. Den första är standardinställningarna. De arbetar för tillförlitlighet, inte prestanda.
    Den andra är en bristande förståelse för mekanismen för att registrera transaktioner. Som standard, efter ett kommando, kommer SQlite att utföra transaktionen (det vill säga vänta tills databasen är i ett konsekvent tillstånd innan du stänger av strömmen). Beroende på paranoialäget kommer SQLite att spendera från 50 till 300 ms på detta (väntar på slutet av att skriva data till disken).
    Vad ska jag göra? Jag behöver infoga 100 tusen poster och det snabbt!
    Ta bort index, slå på synkroniseringsläget AV (eller NORMAL), infoga i delar av N tusen (N - välj, ta 5000 till att börja med). Innan du infogar en del, gör BEGIN TRANSACTION, efter - COMMIT.
    Men jag hittade ett misstag! Hur rapporterar man?
    Aldrig.

    Saken är den att SQLites popularitet är skrämmande – den finns överallt. Jag skojar inte.
    Och utvecklare ställdes inför en flod av felmeddelanden som antingen orsakades av missförstånd eller var dolda funktionsbegäranden. De stängde faktiskt den direkta acceptansen av rapporter med fel.
    Så du bör registrera dig på e-postlistan och posta ditt problem där och hoppas på det bästa.

    Själv hade jag en situation som jag tolkade som en defekt i SQLIte. Jag beskrev detta i nyhetsbrevet. I nästa version SQLite-beteendet har åtgärdats.

    Ett praktiskt verktyg för att leka med SQLite.

    Fortsättning följer.

    Taggar:

    • sqlite
    • sql
    • rdbms
    • Databas
    Lägg till taggar

    Introduktion

    SQLite är en relationsdatabas som kan frågas med hjälp av språket SQL-frågor. Databasen stöder inte allt SQL-funktioner och är sämre i funktionalitet än andra utvecklade DBMS, men är ganska lämplig för att lagra och hämta information.

    Skillnad mellan SQLite och MySQL och liknande DBMS

    Klassiska DBMS, som MySQL (liksom MS SQL, Oracle, PostgreeSQL) består av en separat server som stöder databasen och lyssnar på en specifik port för klientförfrågningar. Kunden kan också vara PHP-tillägg, som implementerar gränssnittet genom vilket förfrågningar till databasen görs. SQLite-motorn och dess gränssnitt är implementerade i ett bibliotek, vilket ökar hastigheten på exekveringen av frågor. Denna server kallas ofta inbyggt.

    Kommentar

    Andra databaser, som MySQL, har också en inbyggd server, men användningen av den kräver licensavgifter och används därför inte i stor utsträckning i världen med öppen källkod.

    SQLite är en typlös databas. Mer exakt finns det bara två typer - heltal "heltal" och text "text". Dessutom används "heltal" huvudsakligen för den primära nyckeln i tabellen, och "text" kommer att användas för återstående data. Längden på strängen som skrivs till textfältet kan vara vilken längd som helst.

    Funktioner i SQLite

    Alla databaser lagras i filer, en fil per databas. Antalet databaser, såväl som tabeller i dem, är endast begränsat fritt utrymme tillgänglig på sajten. Och den maximala möjliga storleken på en databas är 2 TB.

    Eftersom all data lagras i filer finns det inga problem med att överföra en databas från en värd till en annan - du behöver bara kopiera motsvarande filer.

    Installerar SQLite

    I PHP5 är SQLite-stöd installerat och aktiverat som standard.

    Installation under Windows: För att installera SQLite måste du ladda ner och kopiera "php_sqlite.dll"-biblioteket till extensionsmappen, som kan laddas ner från länken: http://snaps.php.net/win32/PECL_STABLE/php_sqlite.dll. Sedan måste du avkommentera (eller lägga till) raden "extension=php_sqlite.dll" i filen "php.ini". För att SQLite ska fungera korrekt måste du också avkommentera raden "extension=php_pdo.dll".

    Kommentar

    Kommentar

    Biblioteket "php_pdo.dll" måste laddas innan "php_sqlite.dll" laddas. Det vill säga i php.ini ska raden "extension=php_sqlite.dll" visas efter "extension=php_pdo.dll".

    Installation under Unix: Ladda ner den senaste versionen av SQLite från den officiella webbplatsen (http://sqlite.org/download.html). Läs "INSTALLERA"-filen som medföljer källmodultesterna. Eller använd helt enkelt PEAR installationskommandot: "pear install sqlite".

    Arbeta med SQLite

    Skapande av databas: För att skapa en ny databas måste du använda funktionen sqlite_open() . Om databasen vars namn anges i parametern "filnamn" inte existerar, kommer funktionen att skapa en ny databas med namnet "filnamn" och returnera databasidentifieraren.

    Resurs sqlite_open (sträng filnamn [, int mode [, sträng &felmeddelande]])

    Manuset nedan visar skapandet ny bas data:

    // Skapa en databas

    om (! $db ) avsluta( "Det gick inte att skapa databas!");
    ?>

    Som ett resultat kommer vi i mappen med skriptet att ha en fil med namnet "my_database.db" - vår databas.

    Skapa tabeller: Alla frågor till databasen utförs av funktionen sqlite_query() som har följande syntax:

    Resource sqlite_query (resurs dbhandle, strängfråga)

    Kommentar

    Att arbeta med SQLite som vilken som helst relationsbas data med hjälp av frågespråket SQL. Därför kan du skapa en datatabell med den traditionella CREATE TABLE-frågan, infoga en post med INSERT uttalande, hämta posten med SELECT och uppdatera befintlig post med en UPPDATERINGsbegäran.

    Exemplet nedan skapar en tabelltabell1 som innehåller tre fält: ett heltalsfält-id, som fungerar som primärnyckel, och två textfält fält1 och fält2.

    $db = sqlite_open("min_databas.db" );
    if (! $db ) exit();
    "SKAPA TABELL tabell1
    (id INTEGER PRIMARY KEY,
    fält1 TEXT,
    field2 TEXT);
    "
    );
    if (! $query_table ) exit();
    $query_insert = sqlite_query ($db, "INSERT INTO table1(field1, field2) VALUES ("PHP5", "Apache");");
    om (! $query_insert ) avsluta( "Kan inte skriva data till tabellen!");
    ?>

    Efter att ha skapat tabellen läggs en post till den som innehåller raderna "PHP5" och "Apache", id-fältet får automatiskt värdet 1.

    Mata ut data från databasen: För att visa data från tabeller används samma funktion - sqlite_query(). Om flera poster hämtas ska hämtningsresultatet bearbetas med en while()-loop och funktionen sqlite_fetch_array() som har följande syntax:

    Array sqlite_fetch_array (resursresultat [, int resultattyp [, bool decode_binary]])

    Nedan finns ett skript som visar utdata från flera poster från databasen:

    // Skapa en ny databas
    $db = sqlite_open("min_databas.db" );
    om (! $db ) avsluta( "Det går inte att skapa databas!");
    // Skapa tabell "tabell1" i databasen
    $query_table = sqlite_query ($db, "SKAPA TABELL tabell1
    (id INTEGER PRIMARY KEY,
    /* id kommer automatiskt att bli automatiskt ökande */
    fält1 TEXT,
    field2 TEXT);
    "
    );
    om (! $query_table ) avsluta( "Det går inte att skapa tabell i databasen!");
    // Skriv något till bordet
    sqlite_query($db, );
    sqlite_query($db, );
    sqlite_query($db, );
    // Låt oss ta ett urval av data
    $res = sqlite_query ($db, "SELECT * FROM tabell1;" );
    while ($array = sqlite_fetch_array ($res))
    {

    " );
    }
    ?>

    Som ett resultat av skriptet får vi:

    PHP5+Apache (post-id:1)

    Redigera ett inlägg: För att ändra ett fält kommer vi att använda funktionen sqlite_query() och skicka en uppdateringsbegäran till den (UPDATE).

    // Skapa en ny databas
    $db = sqlite_open("min_databas.db" );
    om (! $db ) avsluta( "Det går inte att skapa databas!");
    // Skapa tabell "tabell1" i databasen
    $query_table = sqlite_query ($db, "SKAPA TABELL tabell1
    (id INTEGER PRIMARY KEY,
    /* id kommer automatiskt att bli automatiskt ökande */
    fält1 TEXT,
    field2 TEXT);
    "
    );
    om (! $query_table ) avsluta( "Det går inte att skapa tabell i databasen!");
    // Skriv något till bordet
    sqlite_query ($db, "INSERT INTO table1(field1, field2) VALUES ("PHP5+", "Apache");");
    sqlite_query ($db, "INSERT INTO table1(field1, field2) VALUES ("SQLite - ", "cool sak");");
    sqlite_query ($db, "INSERT INTO table1(field1, field2) VALUES ("Besök ", "sqlite.org");");
    // Ändra fältet med id=1
    sqlite_query ($db, "UPPDATERA tabell1 SET field2="Apache+Linux" WHERE id=1;");
    // Låt oss ta ett urval av data

    // I en loop kommer vi att visa alla mottagna data

    {
    echo($array [ "fält1" ]. $array [ "fält2" ]. " (inmatnings-id: " . $array [ "id" ]. ")
    " );
    }
    ?>

    Som ett resultat får vi:

    PHP5+Apache+Linux (post-id:1)
    SQLite är en cool sak (inläggs-id: 2)
    besök sqlite.org (post-id:3)

    Ta bort en post från en tabell: För att radera en post från en tabell måste du skicka en raderingsbegäran (DELETE) till funktionen sqlite_query().

    // Skapa en ny databas
    $db = sqlite_open("min_databas.db" );
    om (! $db ) avsluta( "Det går inte att skapa databas!");
    // Skapa tabell "tabell1" i databasen
    $query_table = sqlite_query ($db, "SKAPA TABELL tabell1
    (id INTEGER PRIMARY KEY,
    /* id kommer automatiskt att bli automatiskt ökande */
    fält1 TEXT,
    field2 TEXT);
    "
    );
    om (! $query_table ) avsluta( "Det går inte att skapa tabell i databasen!");
    // Skriv något till bordet
    sqlite_query ($db, "INSERT INTO table1(field1, field2) VALUES ("PHP5+", "Apache");");
    sqlite_query ($db, "INSERT INTO table1(field1, field2) VALUES ("SQLite - ", "cool sak");");
    sqlite_query ($db, "INSERT INTO table1(field1, field2) VALUES ("Besök ", "sqlite.org");");
    // Ta bort fältet med id=2
    sqlite_query ($db, "RADERA FRÅN tabell1 WHERE id=2;");
    // Låt oss ta ett urval av data
    $query = sqlite_query ($db, "SELECT * FROM tabell1;" );
    // I en loop kommer vi att visa alla mottagna data
    while ($array = sqlite_fetch_array ($query ))
    {
    echo($array [ "fält1" ]. $array [ "fält2" ]. " (inmatnings-id: " . $array [ "id" ]. ")
    " );
    }
    ?>

    Detta är ett bibliotek skrivet i C-språk som ger arbete med SQL. Detta verktyg tillhör Relational Database Management Systems. De flesta SQL-databaser fungerar på klient/serverbasis. Låt oss ta MySQL till exempel. Under drift tas data från MySQL-servern och skickas som ett svar på begäran. Vid användning av SQLite kommer data att tas direkt från disken, d.v.s. du behöver inte kontakta servern.

    Installation

    Vi kommer att interagera med databasen via kommandoradsgränssnittet sqlite3(CLI) på Linux. Arbeta med sqlite3 CLI i MAC OS och Windows utförs på samma sätt, dock rekommenderar jag att du lägger 5 minuter på att installera den virtuella maskinen för att inte belamra din dator med onödig programvara.

    För att installera sqlite3 på Linux, kör kommandot:

    sudo apt-get installera sqlite3 libsqlite3-dev

    Som ett resultat kommer din maskin att ha sqlite3. För att installera det här verktyget på andra operativsystem, följ instruktionerna. För att starta sqlite, kör kommandot sqlite3 i konsolen. Resultatet ska bli så här:

    Den andra raden innehåller en ledtråd om att för att få hjälp måste du köra kommandot.help. Låt oss göra det. Som ett resultat kommer vi att se Metakommandon och deras beskrivning.

    Metakommandon

    Metakommandon- designad för generering av tabeller och andra administrativa operationer. De slutar alla punkt. Låt oss gå igenom listan över kommandon som kan vara användbara:

    Standardkommandon

    Låt oss nu gå igenom listan standardkommandon sqlite3, som är designade för att interagera med databasen. Standardkommandon kan delas in i tre grupper:

    • Data Beskrivning Språk DDL: Kommandon för att skapa en tabell, ändra och ta bort databaser, tabeller och mer.
  • DML Data Management Language: tillåter användaren att manipulera data (lägg till/ändra/ta bort).
  • DQL frågespråk: Tillåter datahämtning.
  • Anteckningen: SQLite stöder också många andra kommandon, en lista över vilka kan hittas. Eftersom den här lektionen är avsedd för nybörjare, kommer vi att begränsa oss till den listade uppsättningen kommandon.

    SQLite databasfiler är plattformsoberoende. De kan placeras på olika typer av enheter.

    • E-post
    • En kommentar

    Av alla dessa fält kan endast webbplatsadressen vara tom. Vi kan också införa en kolumn för numrering av kommentarer. Låt oss kalla det post_id.

    Låt oss nu definiera datatyperna för var och en av kolumnerna:

    Attribut Data typ
    post_id HELTAL
    namn TEXT
    e-post TEXT
    webbadress TEXT
    kommentar TEXT

    Du kommer att kunna hitta alla datatyper som stöds i SQLite3.

    Det bör också noteras att i SQLite3 kan data som infogas i en kolumn skilja sig från den angivna typen. Detta kommer inte att fungera i MySQL.

    Låt oss nu skapa databasen. Om du fortfarande är i sqlite3-gränssnittet, skriv kommandot.quit för att avsluta. Ange nu:

    sqlite3 comment_section.db

    Som ett resultat kommer vi att ha en fil i den aktuella katalogen comment_section.db.

    Anteckningen: Om du inte anger ett filnamn kommer sqlite3 att skapa en temporär databas.

    Skapa ett bord

    För att lagra kommentarer måste vi skapa en tabell. Låt oss kalla det kommentarer. Vi kör kommandot:

    CREATE TABLE-kommentarer (post_id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL, email TEXT NOT NULL, website_url TEXT NULL, comment TEXT NOT NULL);

    NOT NULL kommer att säkerställa att cellen inte innehåller ett nullvärde. PRIMARY KEY och AUTOINCREMENT utökar fältets möjligheter post_id.

    För att verifiera att tabellen har skapats, kör metakommandot .tables. Som ett resultat ser vi vår kommentarstabell.

    Anteckningen: För att få tabellstrukturen, skriv .schema comments

    Nu kan vi lägga in data i tabellen.

    INFOGA RADER

    Låt oss anta att vi måste göra följande post:

    Namn: Shivam Mamgain E-post: [e-postskyddad] Webbplats: shivammg.blogspot.com Kommentar: Bra handledning för nybörjare.

    För att infoga kommer vi att använda kommandot FÖRA IN.

    INFOGA I kommentarer (namn, e-post, website_url, kommentar) VÄRDEN ("Shivam Mamgain", " [e-postskyddad]", "shivammg.blogspot.com", "Bra handledning för nybörjare.");

    Det finns inget behov av att ange ett värde för post_id eftersom den kommer att genereras automatiskt tack vare AUTOINCREMENT-inställningen.

    För att fylla din hand kan du infoga några fler rader.

    PROV

    För att hämta data använder vi kommandot VÄLJ.

    SELECT post_id, name, email, website_url, comment FROM comments;

    Samma begäran kan se ut så här:

    VÄLJ * FRÅN kommentarer;

    Som ett resultat kommer alla rader att extraheras från tabellen. Resultatet kan visas utan kolumnavgränsning och utan rubrik. För att fixa detta gör vi:

    För att visa rubriken anger du .headers ON .

    För att visa kolumner, kör kommandot .mode column .

    Vi genomför VÄLJ begär igen.

    Anteckningen: Visningstypen kan ändras med metakommandot .mode.

    UPPDATERING

    Låt oss anta att fältet e-post för användaren måste 'Shivam Mamgain' ändras till ' [e-postskyddad]’. Vi kör följande kommando:

    Som ett resultat kommer posten att ändras.

    Anteckningen: Kolumnvärde namn kanske inte är unik, så mer än en rad kan påverkas av kommandot. För alla användare där värdet namn= 'Shivam Mamgain', fält e-post kommer att ändras till ' [e-postskyddad]’. För att ändra en specifik rad måste du spåra den med hjälp av fältet post_id. Vi definierade det som PRIMARY KEY, vilket säkerställer värdets unika karaktär.





    

    2024 gtavrl.ru.