<p>
    The Databases Service allows you to store your application and users' data and fetch it using different supported queries.
    You can organize your data into a three-level hierarchy, which are databases, collections, and documents. 
    Each database is a group of collections, each collection is a group of documents that share the same schema, and each document contains a set of data.
</p>

<p>    
    In addition, the Databases Service provides built-in validation to check the integrity of your incoming data, custom indexing for query performance, relationships to link data, and a flexible permissions mechanism to easily segment data between different users, teams, and roles.
    You can also use the Appwrite <a href="/docs/realtime">Realtime API</a> to subscribe to live changes in your database.
</p>

<h2><a href="/docs/databases#databases" id="databases">Create Your Databases</a></h2>
<p>
    Appwrite's Databases Service allows you to create multiple databases. Each database can contain many collections and can be backed by a different database adapter in future versions.
</p>

<p>
    You can create your database by adding it to your Appwrite project's dashboard. Access the Databases Service settings from your project's left-hand navigation panel.
    To create a new database, click the <b>Create Database</b> button. Name your new database, and optionally provide a custom database ID.
</p>

<p>
    You can also create databases with the <a href="/docs/command-line">Appwrite CLI</a> or the <a href="/docs/getting-started-for-server">Appwrite Server SDKs</a>.
</p>

<h2><a href="/docs/databases#collection" id="collection">Create Your Collections</a></h2>
<p>
    Appwrite uses collections as containers of documents. The terms collections and documents are used because the Appwrite JSON REST API resembles the API of a traditional NoSQL database. That said, internally, Appwrite will support both SQL and NoSQL database adapters like MariaDB, MySQL, or MongoDB. When working with an SQL adapter, Appwrite will treat your collections as tables and documents as rows on native SQL tables.
</p>

<p>
    To add a collection to a database, first navigate to the desired database's dashboard. In the database's dashboard, click the <b>Add Collection</b> button and choose your collection's name. For convenience, you can also set a custom ID for your collection instead of an auto-generated ID.
</p>

<p>You can manage your collections programmatically using the <a href="/docs/command-line">Appwrite CLI</a> or one of <a href="/docs/getting-started-for-server">Appwrite Server SDKs</a>. You can manage documents with both the Server and Client SDKs.</p>

<h3><a href="/docs/databases#permissions" id="permissions">Permissions</a></h3>
<p>
    Appwrite provides permissions to restrict access to documents at two levels, document and collection level. When a user has the appropriate type of <a href="/docs/permissions">access permissions</a> granted at <b>either</b> the document or the collection level, they will be able to access or change the document. If the permission field is left empty, Client SDKs cannot access the document.
</p>

<h4>Document Level Permissions</h4>
<p>Document level permissions grant access to individual documents. Document level permissions are only applied if Document Security is enabled in the settings of your collection.</p>

<h4>Collection Level Permissions</h4>
<p>Collection level permissions apply to every document in the collection.</p>

<h2><a href="/docs/databases#attributes" id="attributes">Create Attributes</a></h2>
<p>
    Once you choose your permission model, navigate to your collection's <b>Attributes</b> tab. Attributes are used to define the structure of your documents and help the Appwrite API validate your users' input. Add your first attribute by clicking the <b>Add Attribute</b> button. You can choose between the following types:
</p>
<table cellspacing="0" cellpadding="0" border="0" class="full margin-bottom-large">
    <thead>
        <tr>
            <th style="width: 250px">Attribute</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>string</code></td>
            <td>String attribute.</td>
        </tr>
        <tr>
            <td><code>integer</code></td>
            <td>Integer attribute.</td>
        </tr>
        <tr>
            <td><code>float</code></td>
            <td>Float attribute.</td>
        </tr>
        <tr>
            <td><code>boolean</code></td>
            <td>Boolean attribute.</td>
        </tr>
        <tr>
            <td><code>enum</code></td>
            <td>Enum attribute.</td>
        </tr>
        <tr>
            <td><code>ip</code></td>
            <td>IP address attribute for IPv4 and IPv6.</td>
        </tr>
        <tr>
            <td><code>email</code></td>
            <td>Email address attribute.</td>
        </tr>
        <tr>
            <td><code>url</code></td>
            <td>URL attribute.</td>
        </tr>
        <tr>
            <td><code>relationship</code></td>
            <td>Relationship attribute relates one collection to another. <a href="/docs/databases-relationships">Learn more about relationships.</a></td>
        </tr>
    </tbody>
</table>

<p>
    If an attribute must be populated in all documents, set it as <code>required</code>. If not, you may optionally set a default value. Additionally, decide if the attribute should be a single value or an array of values.
</p>
<p>
    When adding or removing attributes, your requests are processed in the background, indicated by the attribute's <span class="tag">status</span>.
    Depending on your collection's size and other factors, this could take anywhere from a few seconds to a few minutes to complete. You are able to create a document while your attributes are still being processed, however you are not able to use the attributes on the documents until they are <span class="tag">available</span>.
</p>

<h3><a href="/docs/databases#create-documents" id="create-documents">Create Documents</a></h3>
<p>
    Navigate to the <b>Documents</b> tab of your collection and click the <b>Add Document</b> button, or add a document programmatically:
</p>
<ul class="phases clear" data-ui-phases>
    <li>
        <h3>Web</h3>
        <div class="ide" data-lang="javascript" data-lang-label="Web SDK">
            <pre class="line-numbers"><code class="prism language-javascript" data-prism>import { Client, Databases, ID } from "appwrite";

const client = new Client()
    .setEndpoint('https://cloud.appwrite.io/v1')
    .setProject('[PROJECT_ID]');

const databases = new Databases(client);

const promise = databases.createDocument(
    '[DATABASE_ID]',
    '[COLLECTION_ID]',
    ID.unique(),
    {}
);

promise.then(function (response) {
    console.log(response);
}, function (error) {
    console.log(error);
});</code></pre>
        </div>
    </li>
    <li>
        <h3>Flutter</h3>
        <div class="ide" data-lang="dart" data-lang-label="Flutter SDK">
            <pre class="line-numbers"><code class="prism language-dart" data-prism>import 'package:appwrite/appwrite.dart';

void main() async {
    final client = Client()
        .setEndpoint('https://cloud.appwrite.io/v1')
        .setProject('[PROJECT_ID]');

    final databases = Databases(client);

    try {
        final document = databases.createDocument(
            databaseId: '[DATABASE_ID]',
            collectionId: '[COLLECTION_ID]',
            documentId: ID.unique(),
            data: {}
        );
    } on AppwriteException catch(e) {
        print(e);
    }
}</code></pre>
        </div>
    </li>
    <li>
        <h3>Android</h3>
        <div class="ide" data-lang="kotlin" data-lang-label="Android SDK">
            <pre class="line-numbers"><code class="prism language-kotlin" data-prism>import io.appwrite.Client
import io.appwrite.services.Databases

suspend fun main() {
    val client = Client(applicationContext)
        .setEndpoint("https://cloud.appwrite.io/v1")
        .setProject("[PROJECT_ID]")

    val databases = Databases(client)

    try {
        val document = databases.createDocument(
            databaseId = "[DATABASE_ID]",
            collectionId = "[COLLECTION_ID]",
            documentId = ID.unique(),
            data = mapOf("a" to "b"),
        )
    } catch (e: Exception) {
        Log.e("Appwrite", "Error: " + e.message)
    }
}</code></pre>
        </div>
    </li>
    <li>
        <h3>Apple</h3>
        <div class="ide" data-lang="swift" data-lang-label="Apple SDK">
            <pre class="line-numbers"><code class="prism language-swift" data-prism>import Appwrite
import AppwriteModels

func main() async throws {
    let client = Client()
        .setEndpoint("https://cloud.appwrite.io/v1")
        .setProject("[PROJECT_ID]")

    let databases = Databases(client)

    do {
        let document = try await databases.createDocument(
            databaseId: "[DATABASE_ID]",
            collectionId: "[COLLECTION_ID]",
            documentId: ID.unique(),
            data: [:]
        )
    } catch {
        print(error.localizedDescription)
    }
}</code></pre>
        </div>
    </li>
    <li>
        <h3>GraphQL</h3>
        <div class="ide" data-lang="graphql" data-lang-label="GraphQL">
            <pre class="line-numbers"><code class="prism language-graphql" data-prism>mutation {
    databasesCreateDocument(
        databaseId: "[DATABASE_ID]",
        collectionId: "[COLLECTION_ID]",
        documentId: "[DOCUMENT_ID]",
        data: "{}"
    ) {
        _id
        _collectionId
        _databaseId
        _createdAt
        _updatedAt
        _permissions
        data
    }
}</code></pre>
        </div>
    </li>
</ul>

<h2><a href="/docs/databases#indexes" id="indexes">Indexes</a></h2>
<p>
    Databases use indexes to quickly locate data without having to search through every document for matches.
    To ensure the best performance, Appwrite recommends an index for every attribute queried.
    You can create an index by navigating to your collection's <b>Indexes</b> tab or by using your favorite Server SDK. If you plan to query multiple attributes in a single query, creating an index with <b>all</b> queried attributes will yield optimal performance.
</p>

<p>
    The following indexes are currently supported:
</p>
<table cellspacing="0" cellpadding="0" border="0" class="full margin-bottom-large">
    <thead>
        <tr>
            <th style="width: 250px">Type</th>
            <th>Description</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td><code>key</code></td>
            <td>Plain Index to allow queries.</td>
        </tr>
        <tr>
            <td><code>unique</code></td>
            <td>Unique Index to disallow duplicates.</td>
        </tr>
        <tr>
            <td><code>fulltext</code></td>
            <td>For searching within string attributes. Required for the <a href="/docs/queries#query-class">search</a> query method.</td>
        </tr>
    </tbody>
</table>

<h2><a href="/docs/databases#retrieve" id="retrieve">Retrieving Documents</a></h2>
<p>Documents can be retrieved using the <a href="/docs/client/databases#databasesListDocument">List Document</a> endpoint. Results can be filtered, sorted, and paginated using Appwrite's shared set of query methods. You can find a full guide on querying in the <a href="/docs/queries">Queries Guide</a>.</p>

<ul class="phases clear" data-ui-phases>
    <li>
        <h3>Web</h3>
        <div class="ide" data-lang="javascript" data-lang-label="Web SDK">
            <pre class="line-numbers"><code class="prism language-javascript" data-prism>import { Client, Databases, Query } from "appwrite";

const client = new Client()
    .setEndpoint("https://cloud.appwrite.io/v1")
    .setProject("[PROJECT_ID]")

const databases = new Databases(client);

let promise = databases.listDocuments(
    "[DATABASE_ID]"
    "[COLLECTION_ID]",
    [
        Query.equal('title', 'Avatar')
    ]
);

promise.then(function (response) {
    console.log(response);
}, function (error) {
    console.log(error);
});
</code></pre>
        </div>
    </li>
    <li>
        <h3>Flutter</h3>
        <div class="ide" data-lang="dart" data-lang-label="Flutter SDK">
            <pre class="line-numbers"><code class="prism language-dart" data-prism>import 'package:appwrite/appwrite.dart';

void main() async {
    final client = Client()
        .setEndpoint("https://cloud.appwrite.io/v1")
        .setProject("[PROJECT_ID]")

    final databases = Databases(client);

    try {
        final documents = await databases.listDocuments(
            databaseId: '[DATABASE_ID]',
            collectionId: '[COLLECTION_ID]',
            queries: [
                Query.equal('title', 'Avatar')
            ]
        );
    } on AppwriteException catch(e) {
        print(e);
    }
}</code></pre>
        </div>
    </li>
    <li>
        <h3>Android</h3>
        <div class="ide" data-lang="kotlin" data-lang-label="Android SDK">
            <pre class="line-numbers"><code class="prism language-kotlin" data-prism>
import io.appwrite.Client
import io.appwrite.Query
import io.appwrite.services.Databases

suspend fun main() {
    val client = Client(applicationContext)
        .setEndpoint("https://cloud.appwrite.io/v1")
        .setProject("[PROJECT_ID]")

    val databases = Databases(client)

    try {
        val documents = databases.listDocuments(
            databaseId = "[DATABASE_ID]",
            collectionId = "[COLLECTION_ID]",
            queries = listOf(
                Query.equal("title", "Avatar")
            )
        )
    } catch (e: AppwriteException) {
        Log.e("Appwrite", "Error: " + e.message)
    }
}</code></pre>
        </div>
    </li>
    <li>
        <h3>Apple</h3>
        <div class="ide" data-lang="swift" data-lang-label="Apple SDK">
            <pre class="line-numbers"><code class="prism language-swift" data-prism>import Appwrite
import AppwriteModels

func main() async throws{
    let client = Client()
        .setEndpoint("https://cloud.appwrite.io/v1")
        .setProject("[PROJECT_ID]")

    let databases = Databases(client)

    do {
        let documents = try await databases.listDocuments(
            databaseId: "[DATABASE_ID]",
            collectionId: "[COLLECTION_ID]",
            queries: [
                Query.equal("title", "Avatar")
            ]
        )
    } catch {
        print(error.localizedDescription)
    }
}</code></pre>
        </div>
    </li>
    <li>
        <h3>GraphQL</h3>
        <div class="ide" data-lang="graphql" data-lang-label="GraphQL">
            <pre class="line-numbers"><code class="prism language-graphql" data-prism>query {
    databasesListDocuments(
        databaseId: "[DATABASE_ID]",
        collectionId: "[COLLECTION_ID]"
        queries: ["equal(\"title\", [\"Avatar\"])"]
    ) {
        total
        documents {
            _id
            data
        }
    }
}</code></pre>
        </div>
    </li>
</ul>