Automatische Schemaerkennung verwenden

Automatische Schemaerkennung

Die automatische Schemaerkennung ist für das Laden von Daten in BigQuery und für das Abfragen einer externen Datenquelle verfügbar.

Wenn die automatische Erkennung aktiviert ist, startet BigQuery den Ableitungsvorgang. Zu diesem Zweck wird eine zufällige Datei in der Datenquelle ausgewählt und es werden die ersten 500 Datenzeilen als repräsentative Stichprobe durchsucht. BigQuery überprüft dann jedes Feld und versucht basierend auf den Werten in dieser Stichprobe, diesem Feld einen Datentyp zuzuweisen.

Sie können das erkannte Schema für eine Tabelle auf folgenden Wegen aufrufen:

  • Verwenden Sie die Cloud Console.
  • Verwenden Sie den Befehl bq show des bq-Befehlszeilentools.

Wenn BigQuery Schemas ermittelt, könnte es – in seltenen Fällen – einen Feldnamen ändern, um ihn mit der BigQuery-SQL-Syntax kompatibel zu machen.

Informationen zu Datentypkonvertierungen finden Sie auf den folgenden Seiten:

Daten mithilfe der automatischen Schemaerkennung laden

Wählen Sie eine der folgenden Möglichkeiten, um beim Laden von Daten die automatische Schemaerkennung zu aktivieren:

  • Klicken Sie in der Cloud Console im Abschnitt Schema für Automatisch erkennen auf das Kästchen Schema und Eingabeparameter.
  • Verwenden Sie im bq-Befehlszeilentool den Befehl bq load mit dem Parameter --autodetect.

Wenn die automatische Schemaerkennung aktiviert ist, versucht BigQuery, das Schema für CSV- und JSON-Dateien automatisch abzuleiten. Die Logik zur automatischen Erkennung leitet die Schemafeldtypen ab, indem bis zu den ersten 500 Datenzeilen gelesen werden. Führende Zeilen werden übersprungen, wenn das Flag --skip_leading_rows angegeben ist. Die Feldtypen basieren auf den Zeilen mit den meisten Feldern. Daher sollte die automatische Erkennung wie erwartet funktionieren, solange mindestens eine Datenzeile mit Werten in jeder Spalte/jedem Feld vorhanden ist.

Die automatische Schemaerkennung wird nicht für Avro-, Parquet-, ORC-Dateien, Firestore-Exportdateien oder Datastore-Exportdateien verwendet. Wenn Sie diese Dateien in BigQuery laden, wird das Tabellenschema automatisch aus den selbstbeschreibenden Quelldaten abgerufen.

So verwenden Sie die automatische Schemaerkennung beim Laden von JSON- oder CSV-Daten:

Console

  1. Rufen Sie in der Cloud Console die BigQuery-Seite auf.

    BigQuery aufrufen

  2. Maximieren Sie im Bereich Explorer Ihr Projekt und wählen Sie ein Dataset aus.

  3. Maximieren Sie die Option Aktionen und klicken Sie auf Öffnen.

  4. Klicken Sie im Detailfeld auf Tabelle erstellen.

  5. Gehen Sie auf der Seite Tabelle erstellen im Abschnitt Quelle so vor:

    • Geben Sie unter Create table from (Tabelle erstellen aus) Ihren gewünschten Quelltyp an:
    • Suchen Sie im Quellfeld nach der Datei oder dem Cloud Storage-Bucket oder geben Sie den Cloud Storage-URI ein. In der Cloud Console kann zwar nur ein URI eingefügt werden, aber Platzhalter werden unterstützt. Der Cloud Storage-Bucket muss sich am selben Standort wie das Dataset befinden, das die von Ihnen erstellte Tabelle enthält.

      Screenshot: Datei auswählen

    • Wählen Sie als Dateiformat CSV oder JSON aus.

  6. Gehen Sie auf der Seite Create table (Tabelle erstellen) im Abschnitt Destination (Ziel) so vor:

    • Wählen Sie für Dataset-Name das entsprechende Dataset aus.

      Dataset auswählen.

    • Geben Sie im Feld Tabllenname den Namen der Tabelle ein, die Sie in BigQuery erstellen.

    • Achten Sie darauf, dass Table type (Tabellentyp) auf Native table (Native Tabelle) eingestellt ist.

  7. Klicken Sie auf Tabelle erstellen.

bq

Führen Sie den Befehl bq load mit dem Parameter --autodetect aus.

Optional: Geben Sie das Flag --location an und legen Sie als Wert Ihren Standort fest.

Mit dem folgenden Befehl wird eine Datei mit automatischer Schemaerkennung geladen:

bq --location=LOCATION load \
--autodetect \
--source_format=FORMAT \
DATASET.TABLE \
PATH_TO_SOURCE

Dabei gilt:

  • LOCATION: Name Ihres Standorts. Das Flag --location ist optional. Wenn Sie beispielsweise BigQuery in der Region Tokio verwenden, geben Sie für das Flag den Wert asia-northeast1 an. Mit der Datei ".bigqueryrc" können Sie für den Standort einen Standardwert festlegen.
  • FORMAT: entweder NEWLINE_DELIMITED_JSON oder CSV.
  • DATASET: das Dataset mit der Tabelle, in die Sie Daten laden.
  • TABLE: der Name der Tabelle, in die Sie Daten laden.
  • PATH_TO_SOURCE ist der Speicherort der CSV- oder JSON-Datei.

Beispiele:

Geben Sie den folgenden Befehl ein, um myfile.csv von Ihrem lokalen Computer in eine Tabelle namens mytable zu laden, die in einem Dataset namens mydataset gespeichert ist.

bq load --autodetect --source_format=CSV mydataset.mytable ./myfile.csv

Geben Sie den folgenden Befehl ein, um myfile.json von Ihrem lokalen Computer in eine Tabelle namens mytable zu laden, die in einem Dataset namens mydataset gespeichert ist.

bq load --autodetect --source_format=NEWLINE_DELIMITED_JSON \
mydataset.mytable ./myfile.json

API

  1. Erstellen Sie einen load-Job, der auf die Quelldaten verweist. Weitere Informationen zum Erstellen von Jobs finden Sie unter BigQuery-Jobs programmatisch ausführen. Geben Sie Ihren Standort im Abschnitt jobReference im Attribut location an.

  2. Geben Sie das Datenformat an. Legen Sie dazu das Attribut sourceFormat fest. Wenn Sie die automatische Schemaerkennung verwenden möchten, muss dieser Wert auf NEWLINE_DELIMITED_JSON oder CSV gesetzt werden.

  3. Verwenden Sie das Attribut autodetect, um die automatische Schemaerkennung auf true zu setzen.

Go

Bevor Sie dieses Beispiel ausprobieren, folgen Sie den Schritten zur Einrichtung von Go in der BigQuery-Kurzanleitung zur Verwendung von Clientbibliotheken. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Go API.

import (
	"context"
	"fmt"

	"cloud.google.com/go/bigquery"
)

// importJSONAutodetectSchema demonstrates loading data from newline-delimited JSON data in Cloud Storage
// and using schema autodetection to identify the available columns.
func importJSONAutodetectSchema(projectID, datasetID, tableID string) error {
	// projectID := "my-project-id"
	// datasetID := "mydataset"
	// tableID := "mytable"
	ctx := context.Background()
	client, err := bigquery.NewClient(ctx, projectID)
	if err != nil {
		return fmt.Errorf("bigquery.NewClient: %v", err)
	}
	defer client.Close()

	gcsRef := bigquery.NewGCSReference("gs://cloud-samples-data/bigquery/us-states/us-states.json")
	gcsRef.SourceFormat = bigquery.JSON
	gcsRef.AutoDetect = true
	loader := client.Dataset(datasetID).Table(tableID).LoaderFrom(gcsRef)
	loader.WriteDisposition = bigquery.WriteEmpty

	job, err := loader.Run(ctx)
	if err != nil {
		return err
	}
	status, err := job.Wait(ctx)
	if err != nil {
		return err
	}

	if status.Err() != nil {
		return fmt.Errorf("job completed with error: %v", status.Err())
	}
	return nil
}

Java

import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.FormatOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.TableId;

// Sample to load JSON data with autodetect schema from Cloud Storage into a new BigQuery table
public class LoadJsonFromGCSAutodetect {

  public static void runLoadJsonFromGCSAutodetect() {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.json";
    loadJsonFromGCSAutodetect(datasetName, tableName, sourceUri);
  }

  public static void loadJsonFromGCSAutodetect(
      String datasetName, String tableName, String sourceUri) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);
      LoadJobConfiguration loadConfig =
          LoadJobConfiguration.newBuilder(tableId, sourceUri)
              .setFormatOptions(FormatOptions.json())
              .setAutodetect(true)
              .build();

      // Load data from a GCS JSON file into the table
      Job job = bigquery.create(JobInfo.of(loadConfig));
      // Blocks until this load table job completes its execution, either failing or succeeding.
      job = job.waitFor();
      if (job.isDone()) {
        System.out.println("Json Autodetect from GCS successfully loaded in a table");
      } else {
        System.out.println(
            "BigQuery was unable to load into the table due to an error:"
                + job.getStatus().getError());
      }
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Column not added during load append \n" + e.toString());
    }
  }
}
import com.google.cloud.bigquery.BigQuery;
import com.google.cloud.bigquery.BigQueryException;
import com.google.cloud.bigquery.BigQueryOptions;
import com.google.cloud.bigquery.CsvOptions;
import com.google.cloud.bigquery.Job;
import com.google.cloud.bigquery.JobInfo;
import com.google.cloud.bigquery.LoadJobConfiguration;
import com.google.cloud.bigquery.TableId;

// Sample to load CSV data with autodetect schema from Cloud Storage into a new BigQuery table
public class LoadCsvFromGcsAutodetect {

  public static void main(String[] args) {
    // TODO(developer): Replace these variables before running the sample.
    String datasetName = "MY_DATASET_NAME";
    String tableName = "MY_TABLE_NAME";
    String sourceUri = "gs://cloud-samples-data/bigquery/us-states/us-states.csv";
    loadCsvFromGcsAutodetect(datasetName, tableName, sourceUri);
  }

  public static void loadCsvFromGcsAutodetect(
      String datasetName, String tableName, String sourceUri) {
    try {
      // Initialize client that will be used to send requests. This client only needs to be created
      // once, and can be reused for multiple requests.
      BigQuery bigquery = BigQueryOptions.getDefaultInstance().getService();

      TableId tableId = TableId.of(datasetName, tableName);

      // Skip header row in the file.
      CsvOptions csvOptions = CsvOptions.newBuilder().setSkipLeadingRows(1).build();

      LoadJobConfiguration loadConfig =
          LoadJobConfiguration.newBuilder(tableId, sourceUri)
              .setFormatOptions(csvOptions)
              .setAutodetect(true)
              .build();

      // Load data from a GCS CSV file into the table
      Job job = bigquery.create(JobInfo.of(loadConfig));
      // Blocks until this load table job completes its execution, either failing or succeeding.
      job = job.waitFor();
      if (job.isDone() && job.getStatus().getError() == null) {
        System.out.println("CSV Autodetect from GCS successfully loaded in a table");
      } else {
        System.out.println(
            "BigQuery was unable to load into the table due to an error:"
                + job.getStatus().getError());
      }
    } catch (BigQueryException | InterruptedException e) {
      System.out.println("Column not added during load append \n" + e.toString());
    }
  }
}

Node.js

Bevor Sie dieses Beispiel ausprobieren, folgen Sie den Schritten zur Einrichtung von Node.js in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Angaben finden Sie in der Referenzdokumentation zur BigQuery Node.js API.

// Import the Google Cloud client libraries
const {BigQuery} = require('@google-cloud/bigquery');
const {Storage} = require('@google-cloud/storage');

/**
 * TODO(developer): Uncomment the following lines before running the sample.
 */
// const datasetId = "my_dataset";
// const tableId = "my_table";

/**
 * This sample loads the JSON file at
 * https://storage.googleapis.com/cloud-samples-data/bigquery/us-states/us-states.json
 *
 * TODO(developer): Replace the following lines with the path to your file.
 */
const bucketName = 'cloud-samples-data';
const filename = 'bigquery/us-states/us-states.json';

async function loadJSONFromGCSAutodetect() {
  // Imports a GCS file into a table with autodetected schema.

  // Instantiate clients
  const bigquery = new BigQuery();
  const storage = new Storage();

  // Configure the load job. For full list of options, see:
  // https://cloud.google.com/bigquery/docs/reference/rest/v2/Job#JobConfigurationLoad
  const metadata = {
    sourceFormat: 'NEWLINE_DELIMITED_JSON',
    autodetect: true,
    location: 'US',
  };

  // Load data from a Google Cloud Storage file into the table
  const [job] = await bigquery
    .dataset(datasetId)
    .table(tableId)
    .load(storage.bucket(bucketName).file(filename), metadata);
  // load() waits for the job to finish
  console.log(`Job ${job.id} completed.`);

  // Check the job's status for errors
  const errors = job.status.errors;
  if (errors && errors.length > 0) {
    throw errors;
  }
}
loadJSONFromGCSAutodetect();

PHP

Bevor Sie dieses Beispiel ausprobieren, folgen Sie den Schritten zur Einrichtung von PHP in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur BigQuery PHP API.

use Google\Cloud\BigQuery\BigQueryClient;
use Google\Cloud\Core\ExponentialBackoff;

/** Uncomment and populate these variables in your code */
// $projectId  = 'The Google project ID';
// $datasetId  = 'The BigQuery dataset ID';
// $tableId    = 'us_states';

// instantiate the bigquery table service
$bigQuery = new BigQueryClient([
    'projectId' => $projectId,
]);
$dataset = $bigQuery->dataset($datasetId);
$table = $dataset->table($tableId);

// create the import job
$gcsUri = 'gs://cloud-samples-data/bigquery/us-states/us-states.json';
$loadConfig = $table->loadFromStorage($gcsUri)->autodetect(true)->sourceFormat('NEWLINE_DELIMITED_JSON');
$job = $table->runJob($loadConfig);
// poll the job until it is complete
$backoff = new ExponentialBackoff(10);
$backoff->execute(function () use ($job) {
    print('Waiting for job to complete' . PHP_EOL);
    $job->reload();
    if (!$job->isComplete()) {
        throw new Exception('Job has not yet completed', 500);
    }
});
// check if the job has errors
if (isset($job->info()['status']['errorResult'])) {
    $error = $job->info()['status']['errorResult']['message'];
    printf('Error running job: %s' . PHP_EOL, $error);
} else {
    print('Data imported successfully' . PHP_EOL);
}

Python

Wenn Sie die automatische Schemaerkennung aktivieren möchten, legen Sie das Attribut LoadJobConfig.autodetect auf True fest.

Bevor Sie dieses Beispiel ausprobieren, folgen Sie den Schritten zur Einrichtung von Python in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur  Python API.

from google.cloud import bigquery

# Construct a BigQuery client object.
client = bigquery.Client()

# TODO(developer): Set table_id to the ID of the table to create.
# table_id = "your-project.your_dataset.your_table_name

# Set the encryption key to use for the destination.
# TODO: Replace this key with a key you have created in KMS.
# kms_key_name = "projects/{}/locations/{}/keyRings/{}/cryptoKeys/{}".format(
#     "cloud-samples-tests", "us", "test", "test"
# )
job_config = bigquery.LoadJobConfig(
    autodetect=True, source_format=bigquery.SourceFormat.NEWLINE_DELIMITED_JSON
)
uri = "gs://cloud-samples-data/bigquery/us-states/us-states.json"
load_job = client.load_table_from_uri(
    uri, table_id, job_config=job_config
)  # Make an API request.
load_job.result()  # Waits for the job to complete.
destination_table = client.get_table(table_id)
print("Loaded {} rows.".format(destination_table.num_rows))

Ruby

Bevor Sie dieses Beispiel ausprobieren, folgen Sie den Schritten zur Einrichtung von Ruby in der BigQuery-Kurzanleitung: Clientbibliotheken verwenden. Weitere Informationen finden Sie in der Referenzdokumentation zur BigQuery Ruby API.

require "google/cloud/bigquery"

def load_table_gcs_json_autodetect dataset_id = "your_dataset_id"
  bigquery = Google::Cloud::Bigquery.new
  dataset  = bigquery.dataset dataset_id
  gcs_uri  = "gs://cloud-samples-data/bigquery/us-states/us-states.json"
  table_id = "us_states"

  load_job = dataset.load_job table_id,
                              gcs_uri,
                              format:     "json",
                              autodetect: true
  puts "Starting job #{load_job.job_id}"

  load_job.wait_until_done! # Waits for table load to complete.
  puts "Job finished."

  table = dataset.table table_id
  puts "Loaded #{table.rows_count} rows to table #{table.id}"
end

Automatische Schemaerkennung für externe Datenquellen

Die automatische Schemaerkennung kann für externe Datenquellen in CSV, JSON und Google Tabellen verwendet werden. Wenn die automatische Schemaerkennung aktiviert ist, versucht BigQuery, das Schema automatisch aus den Quelldaten abzuleiten. Wenn Sie die automatische Schemaerkennung für diese Quellen nicht aktivieren, müssen Sie ein explizites Schema angeben.

Die automatische Schemaerkennung wird nicht für selbstbeschreibende externe Dateien, einschließlich Avro-, Parquet- und ORC-Formate, und auch nicht für Firestore- oder Datastore-Exportdateien verwendet. Wenn Sie eine Tabelle erstellen, die mit einem dieser Dateitypen verknüpft ist, ruft BigQuery das Schema automatisch aus den selbstbeschreibenden Quelldaten ab.

Mit der Cloud Console können Sie die automatische Schemaerkennung aktivieren. Klicken Sie dazu die Option Schema und Eingabeparameter für Automatisch erkennen an.

Mit dem bq-Befehlszeilentool können Sie die automatische Schemaerkennung aktivieren, wenn Sie eine Tabellendefinitionsdatei für CSV-, JSON- oder Google Tabellen-Daten erstellen. Wenn Sie eine Tabellendefinitionsdatei mit dem bq-Tool erstellen, übergeben Sie das Flag --autodetect an den Befehl mkdef, um die automatische Schemaerkennung zu aktivieren, oder übergeben Sie das Flag --noautodetect, um die automatische Erkennung zu deaktivieren.

Wenn Sie das Flag --autodetect verwenden, ist die Einstellung autodetect in der Tabellendefinitionsdatei auf true gesetzt. Wenn Sie das Flag --noautodetect verwenden, ist die Einstellung autodetect auf false gesetzt. Wenn Sie beim Erstellen einer Tabellendefinition keine Schemadefinition für die externe Datenquelle angeben und das Flag --noautodetect oder --autodetect nicht verwenden, wird für autodetect standardmäßig true verwendet.

Wenn Sie eine Tabellendefinitionsdatei mithilfe der API erstellen, setzen Sie den Wert des Attributs autodetect auf true oder false. Wenn Sie autodetect auf true setzen, wird die automatische Erkennung aktiviert. Wenn Sie autodetect auf false setzen, wird die automatische Erkennung deaktiviert.

Details der automatischen Erkennung

Neben der Erkennung von Schemadetails wird Folgendes automatisch erkannt:

Komprimierung

BigQuery erkennt die GZIP-kompatible Dateikomprimierung beim Öffnen einer Datei.

CSV-Trennzeichen

BigQuery erkennt die folgenden Trennzeichen:

  • Komma ( , )
  • Senkrechter Strich ( | )
  • Tabulator ( \t )

CSV-Header

BigQuery leitet Header ab, indem es die erste Zeile einer Datei mit anderen Zeilen im Dataset vergleicht. Wenn die erste Zeile nur Strings enthält und die anderen Zeilen andere Datentypen enthalten, geht BigQuery davon aus, dass es sich bei der ersten Zeile um eine Kopfzeile handelt. In diesem Fall weist BigQuery Spaltennamen basierend auf den Feldnamen in der Kopfzeile zu. Die Namen werden möglicherweise entsprechend den Benennungsregeln für Spalten in BigQuery geändert. Zum Beispiel werden Leerzeichen durch Unterstriche ersetzt.

Andernfalls geht BigQuery davon aus, dass die erste Zeile eine Datenzeile ist und weist allgemeine Spaltennamen wie string_field_1 zu. Beachten Sie, dass die Spaltennamen nach dem Erstellen einer Tabelle nicht mehr im Schema aktualisiert werden können. Sie können die Namen jedoch manuell ändern, nachdem die Tabelle erstellt wurde. Eine weitere Option ist die Bereitstellung eines expliziten Schemas anstelle der automatischen Erkennung.

Möglicherweise haben Sie eine CSV-Datei mit einer Kopfzeile, in der alle Datenfelder Strings sind. In diesem Fall erkennt BigQuery nicht automatisch, dass die erste Zeile ein Header ist. Verwenden Sie die Option -skip_leading_rows, um die Kopfzeile zu überspringen. Andernfalls wird der Header als Daten importiert. In diesem Fall sollten Sie auch ein explizites Schema angeben, damit Sie Spaltennamen zuweisen können.

CSV-Zeilenvorschübe in Anführungszeichen

BigQuery erkennt Zeilenvorschubzeichen in Anführungszeichen in einer CSV-Datei und interpretiert das Zeilenvorschubzeichen in Anführungszeichen nicht als Zeilengrenze.

Datums- und Uhrzeitwerte

BigQuery erkennt Datums- und Uhrzeitwerte basierend auf der Formatierung der Quelldaten.

Werte in DATE-Spalten müssen das folgende Format haben: YYYY-MM-DD.

Die Werte in den TIME-Spalten müssen im folgenden Format angegeben werden: HH:MM:SS[.SSSSSS] (die Komponente des Sekundenbruchteils ist optional).

Bei TIMESTAMP-Spalten erkennt BigQuery eine Vielzahl von Zeitstempelformaten, einschließlich, aber nicht beschränkt auf:

  • YYYY-MM-DD HH:MM
  • YYYY-MM-DD HH:MM:SS
  • YYYY-MM-DD HH:MM:SS.SSSSSS
  • YYYY/MM/DD HH:MM

Ein Zeitstempel kann auch einen UTC-Versatz oder den UTC-Zonenbezeichner ("Z") enthalten.

Im Folgenden finden Sie einige Beispiele für Werte, die BigQuery automatisch als Zeitstempelwerte erkennt:

  • 2018-08-19 12:11
  • 2018-08-19 12:11:35.22
  • 2018/08/19 12:11
  • 2018-08-19 07:11:35.220 -05:00

Wenn BigQuery das Format nicht erkennt, wird die Spalte als String-Datentyp geladen. In diesem Fall müssen Sie die Quelldaten vor dem Laden möglicherweise vorverarbeiten. Wenn Sie beispielsweise CSV-Daten aus einer Tabelle exportieren, legen Sie das Datumsformat auf eines der hier gezeigten Beispiele fest. Alternativ können Sie die Daten nach dem Laden in BigQuery umwandeln.

Verschachtelte und wiederkehrende Felder in JSON

BigQuery leitet verschachtelte und wiederkehrende Felder in JSON-Dateien ab. Wenn ein Feldwert ein JSON-Objekt ist, lädt BigQuery die Spalte als RECORD-Typ. Wenn ein Feldwert ein Array ist, lädt BigQuery die Spalte als wiederkehrende Spalte. Ein Beispiel für JSON-Daten mit verschachtelten und wiederkehrenden Daten finden Sie unter Verschachtelte und wiederkehrende JSON-Daten laden.

Tabellensicherheit

Informationen zum Steuern des Zugriffs auf Tabellen in BigQuery finden Sie unter Einführung in die Tabellenzugriffssteuerung.