Le livre "Google BigQuery. Tout sur l'entreposage de données, l'analyse et l'apprentissage automatique "

imageBonjour les Habitants! Êtes-vous intimidĂ© par la nĂ©cessitĂ© de traiter des ensembles de donnĂ©es de pĂ©taoctets? DĂ©couvrez Google BigQuery, un systĂšme de stockage d'informations qui peut consolider les donnĂ©es dans toute l'entreprise, faciliter l'analyse interactive et activer l'apprentissage automatique. Vous pouvez dĂ©sormais stocker, interroger, recevoir et explorer efficacement des donnĂ©es dans un environnement pratique. Walyappa Lakshmanan et Jordan Taijani vous apprendront Ă  travailler dans un entrepĂŽt de donnĂ©es moderne en utilisant toute la puissance d'un cloud public Ă©volutif et sans serveur. Avec ce livre, vous allez: - Plonger dans les rouages ​​de BigQuery - Explorer les types de donnĂ©es, les fonctions et les opĂ©rateurs pris en charge par Big Query - Optimiser les requĂȘtes et mettre en Ɠuvre des schĂ©mas pour amĂ©liorer les performances ou rĂ©duire les coĂ»ts - En savoir plus sur les SIG, les voyages dans le temps, DDL / DML.fonctions personnalisĂ©es et scripts SQL - RĂ©solvez de nombreux dĂ©fis d'apprentissage automatique - DĂ©couvrez comment protĂ©ger les donnĂ©es, suivre les performances et authentifier les utilisateurs.





Minimisation des coĂ»ts de rĂ©seau BigQuery est un service rĂ©gional disponible dans le monde entier. Par exemple, si vous demandez un ensemble de donnĂ©es stockĂ© dans la rĂ©gion UE, la demande s'exĂ©cutera sur des serveurs situĂ©s dans un centre de donnĂ©es de l'Union europĂ©enne. Pour que vous puissiez stocker les rĂ©sultats de la requĂȘte dans une table, celle-ci doit se trouver dans un ensemble de donnĂ©es qui se trouve Ă©galement dans la rĂ©gion UE. Cependant, l'API REST de BigQuery peut ĂȘtre appelĂ©e (c'est-Ă -dire exĂ©cuter une requĂȘte) de n'importe oĂč dans le monde, mĂȘme Ă  partir d'ordinateurs extĂ©rieurs Ă  GCP. Lorsque vous travaillez avec d'autres ressources GCP, telles que Google Cloud Storage ou Cloud Pub / Sub, les meilleures performances sont obtenues si elles se trouvent dans la mĂȘme rĂ©gion que l'ensemble de donnĂ©es. Par consĂ©quent, si la requĂȘte est exĂ©cutĂ©e Ă  partir d'une instance Compute Engine ou d'un cluster Cloud Dataproc, la surcharge du rĂ©seau sera minimale,si l'instance ou le cluster se trouve Ă©galement dans la mĂȘme rĂ©gion que l'ensemble de donnĂ©es demandĂ©. Lorsque vous accĂ©dez Ă  BigQuery depuis l'extĂ©rieur de GCP, tenez compte de la topologie de votre rĂ©seau et essayez de minimiser le nombre de sauts entre l'ordinateur client et le centre GCP oĂč rĂ©side l'ensemble de donnĂ©es.



RĂ©ponses



concises et incomplĂštes En accĂ©dant directement Ă  l'API REST, la surcharge du rĂ©seau peut ĂȘtre rĂ©duite en acceptant des rĂ©ponses concises et incomplĂštes. Pour accepter les rĂ©ponses compressĂ©es, vous pouvez spĂ©cifier dans l'en-tĂȘte HTTP que vous ĂȘtes prĂȘt Ă  accepter une archive gzip et vous assurer que la ligne "gzip" est prĂ©sente dans l'en-tĂȘte User-Agent, par exemple:



Accept-Encoding: gzip
User-Agent: programName (gzip)


Dans ce cas, toutes les rĂ©ponses seront compressĂ©es Ă  l'aide de gzip. Par dĂ©faut, les rĂ©ponses BigQuery contiennent tous les champs rĂ©pertoriĂ©s dans la documentation. Cependant, si nous savons quelle partie de la rĂ©ponse nous intĂ©resse, nous pouvons demander Ă  BigQuery de n'envoyer que cette partie, rĂ©duisant ainsi la surcharge du rĂ©seau. Par exemple, dans ce chapitre, nous avons vu comment obtenir des informations complĂštes sur un travail Ă  l'aide de l'API Jobs. Si vous n'ĂȘtes intĂ©ressĂ© que par un sous-ensemble de la rĂ©ponse complĂšte (par exemple, uniquement les Ă©tapes du plan de requĂȘte), vous pouvez spĂ©cifier les champs d'intĂ©rĂȘt pour limiter la taille de la rĂ©ponse:



JOBSURL="https://www.googleapis.com/bigquery/v2/projects/$PROJECT/jobs"
FIELDS="statistics(query(queryPlan(steps)))"
curl --silent \
    -H "Authorization: Bearer $access_token" \
    -H "Accept-Encoding: gzip" \
    -H "User-Agent: get_job_details (gzip)" \
    -X GET \
    "${JOBSURL}/${JOBID}?fields=${FIELDS}" \
| zcat


Remarque: il indique également que nous acceptons les données compressées gzip.



Combiner plusieurs demandes dans des packages



Lorsque vous utilisez l'API REST, il est possible de combiner plusieurs appels d'API BigQuery Ă  l'aide du type de contenu multipart / mixte et des requĂȘtes HTTP imbriquĂ©es dans chaque partie. Le corps de chaque partie spĂ©cifie l'opĂ©ration HTTP (GET, PUT, etc.), le chemin vers l'URL, les en-tĂȘtes et le corps. En rĂ©ponse, le serveur enverra une seule rĂ©ponse HTTP avec le type de contenu multipart / mixed, dont chaque partie contiendra la rĂ©ponse (dans l'ordre) Ă  la requĂȘte correspondante dans la requĂȘte batch. Bien que les rĂ©ponses soient renvoyĂ©es dans un ordre spĂ©cifique, le serveur peut traiter les appels dans n'importe quel ordre. Par consĂ©quent, une demande par lots peut ĂȘtre considĂ©rĂ©e comme un groupe de demandes exĂ©cutĂ©es en parallĂšle. Voici un exemple d'envoi d'une requĂȘte par lots pour obtenir des dĂ©tails Ă  partir des plans d'exĂ©cution des cinq derniĂšres requĂȘtes de notre projet. Nous utilisons d'abord l'outil de ligne de commande BigQuery,pour obtenir les cinq derniĂšres quĂȘtes rĂ©ussies:



# 5   
JOBS=$(bq ls -j -n 50 | grep SUCCESS | head -5 | awk '{print $1}')


La demande est envoyée au point de terminaison BigQuery pour un traitement par lots:



BATCHURL="https://www.googleapis.com/batch/bigquery/v2"
JOBSPATH="/projects/$PROJECT/jobs"
FIELDS="statistics(query(queryPlan(steps)))"


Vous pouvez définir des demandes individuelles dans le chemin de l'URL:



request=""
for JOBID in $JOBS; do
read -d '' part << EOF
--batch_part_starts_here
GET ${JOBSPATH}/${JOBID}?fields=${FIELDS}
EOF
request=$(echo "$request"; echo "$part")
done


Ensuite, vous pouvez envoyer la demande en tant que demande composée:



curl --silent \
   -H "Authorization: Bearer $access_token" \
   -H "Content-Type: multipart/mixed; boundary=batch_part_starts_here" \
   -X POST \
   -d "$request" \
   "${BATCHURL}"


Lecture groupée à l'aide de l'API de stockage BigQuery



Dans le chapitre 5, nous avons discutĂ© de l'utilisation de l'API REST BigQuery et des bibliothĂšques clientes pour Ă©numĂ©rer les tables et rĂ©cupĂ©rer les rĂ©sultats des requĂȘtes. L'API REST renvoie les donnĂ©es sous forme d'enregistrements paginĂ©s qui conviennent mieux aux ensembles de rĂ©sultats relativement petits. Cependant, avec l'avĂšnement du machine learning et des outils d'extraction, de transformation et de chargement (ETL) distribuĂ©s, les outils externes nĂ©cessitent dĂ©sormais un accĂšs en masse rapide et efficace au rĂ©fĂ©rentiel BigQuery gĂ©rĂ©. Cet accĂšs en lecture groupĂ©e est fourni dans l'API BigQuery Storage via le protocole d'appel de procĂ©dure Ă  distance (RPC). Avec l'API BigQuery Storage, les donnĂ©es structurĂ©es sont transmises sur le rĂ©seau dans un format de sĂ©rialisation binaire qui correspond plus Ă©troitement au format de stockage de donnĂ©es en colonnes.Cela fournit une parallĂ©lisation supplĂ©mentaire de l'ensemble de rĂ©sultats sur plusieurs consommateurs.



Les utilisateurs finaux n'utilisent pas directement l'API BigQuery Storage. Au lieu de cela, ils utilisent Cloud Dataflow, Cloud Dataproc, TensorFlow, AutoML et d'autres outils qui utilisent l'API de stockage pour lire les données directement à partir du stockage géré plutÎt que via l'API BigQuery.



Étant donnĂ© que l'API Storage accĂšde directement aux donnĂ©es stockĂ©es, l'autorisation d'accĂ©der Ă  l'API BigQuery Storage est diffĂ©rente de l'API BigQuery existante. Les autorisations de l'API BigQuery Storage doivent ĂȘtre configurĂ©es indĂ©pendamment des autorisations BigQuery.



L'API BigQuery Storage offre plusieurs avantages aux outils qui lisent les donnĂ©es directement Ă  partir du stockage gĂ©rĂ© BigQuery. Par exemple, les consommateurs peuvent lire des jeux d'enregistrements disjoints Ă  partir d'une table Ă  l'aide de plusieurs threads (par exemple, en autorisant des lectures distribuĂ©es de donnĂ©es Ă  partir de diffĂ©rents serveurs de production dans Cloud Dataproc), en segmentant dynamiquement ces threads (rĂ©duisant ainsi la latence de la queue, ce qui peut ĂȘtre un problĂšme sĂ©rieux pour les tĂąches MapReduce) , sĂ©lectionnez un sous-ensemble de colonnes Ă  lire (pour ne transmettre que les fonctionnalitĂ©s utilisĂ©es par le modĂšle aux structures d'apprentissage automatique), filtrez les valeurs de colonne (rĂ©duisez la quantitĂ© de donnĂ©es transmises sur le rĂ©seau) et en mĂȘme temps assurez la cohĂ©rence des instantanĂ©s (c'est-Ă -dire la lecture des donnĂ©es Ă  partir d'un certain point dans le temps).



Dans le chapitre 5, nous avons abordĂ© l'utilisation de l'extension %% bigquery dans Jupyter Notebook pour charger les rĂ©sultats de la requĂȘte dans DataFrames. Cependant, les exemples utilisaient des ensembles de donnĂ©es relativement petits - d'une douzaine Ă  plusieurs centaines d'enregistrements. Est-il possible de charger l'ensemble de donnĂ©es london_bicycles (24 millions d'enregistrements) dans un DataFrame? Oui, vous pouvez, mais dans ce cas, vous devez utiliser l'API de stockage, et non l'API BigQuery, pour charger des donnĂ©es dans le DataFrame. Tout d'abord, vous devez installer la bibliothĂšque cliente de l'API de stockage Python avec la prise en charge d'Avro et de pandas. Cela peut ĂȘtre fait avec la commande



%pip install google-cloud-bigquery-storage[fastavro,pandas]


Ensuite, il ne reste plus qu'à utiliser l'extension %% bigquery, comme auparavant, mais ajouter un paramÚtre qui nécessite l'utilisation de l'API de stockage:



%%bigquery df --use_bqstorage_api --project $PROJECT
SELECT 
   start_station_name 
   , end_station_name 
   , start_date 
   , duration
FROM `bigquery-public-data`.london_bicycles.cycle_hire


Notez que nous utilisons ici la capacitĂ© de l'API de stockage Ă  fournir un accĂšs direct aux colonnes individuelles; il n'est pas nĂ©cessaire de lire l'intĂ©gralitĂ© de la table BigQuery dans un DataFrame. Si la requĂȘte renvoie une petite quantitĂ© de donnĂ©es, l'extension utilisera automatiquement l'API BigQuery. Par consĂ©quent, ce n'est pas effrayant si vous indiquez toujours cet indicateur dans les cellules du cahier. Pour activer l'indicateur --usebqstorageapi dans toutes les cellules du bloc-notes, vous pouvez dĂ©finir l'indicateur de contexte:



import google.cloud.bigquery.magics
google.cloud.bigquery.magics.context.use_bqstorage_api = True


Choisir un format de stockage efficace



Les performances d'une requĂȘte dĂ©pendent de l'emplacement et du format de stockage des donnĂ©es qui composent la table. En gĂ©nĂ©ral, moins la requĂȘte doit effectuer des recherches ou des conversions de type, meilleures sont les performances.



Sources de données internes et externes



BigQuery prend en charge l'interrogation de sources de données externes telles que Google Cloud Storage, Cloud Bigtable et Google Sheets, mais vous ne pouvez obtenir les meilleures performances qu'à partir de vos propres tables.



Nous vous recommandons d'utiliser BigQuery comme référentiel de données analytiques pour toutes vos données structurées et semi-structurées. Les sources de données externes sont mieux utilisées pour le stockage intermédiaire (Google Cloud Storage), les importations en direct (Cloud Pub / Sub, Cloud Bigtable) ou les mises à jour périodiques (Cloud SQL, Cloud Spanner). Ensuite, configurez votre pipeline de données pour charger les données selon un calendrier à partir de ces sources externes dans BigQuery (voir le chapitre 4).



Si vous devez demander des données à Google Cloud Storage, enregistrez-les si possible dans un format de colonne compressé (tel que Parquet). Utilisez des formats basés sur des enregistrements tels que JSON ou CSV en dernier recours.



Gestion du cycle de vie du bucket de préparation



Si vous importez des donnĂ©es dans BigQuery aprĂšs les avoir placĂ©es dans Google Cloud Storage, assurez-vous de les supprimer du cloud aprĂšs l'importation. Si vous utilisez le pipeline ETL pour charger des donnĂ©es dans BigQuery (pour les transformer de maniĂšre significative ou ne laisser qu'une partie des donnĂ©es en cours de route), vous souhaiterez peut-ĂȘtre enregistrer les donnĂ©es d'origine dans Google Cloud Storage. Dans ce cas, vous pouvez contribuer Ă  rĂ©duire les coĂ»ts en dĂ©finissant des rĂšgles de gestion du cycle de vie du bucket qui rĂ©trogradent le stockage dans Google Cloud Storage.



Voici comment activer la gestion du cycle de vie du bucket et configurer le déplacement automatique des données des régions fédérées ou des classes standard de plus de 30 jours vers le stockage Nearline, et les données stockées dans Nearline Storage pendant plus de 90 jours vers Coldline Storage:



gsutil lifecycle set lifecycle.yaml gs://some_bucket/


Dans cet exemple, le fichier lifecycle.yaml contient le code suivant:



{
"lifecycle": {
  "rule": [
  {
   "action": {
    "type": "SetStorageClass",
    "storageClass": "NEARLINE"
   },
   "condition": {
    "age": 30,
    "matchesStorageClass": ["MULTI_REGIONAL", "STANDARD"]
   }
 },
 {
  "action": {
   "type": "SetStorageClass",
   "storageClass": "COLDLINE"
  },
  "condition": {
   "age": 90,
   "matchesStorageClass": ["NEARLINE"]
  }
 }
]}}


Vous pouvez utiliser la gestion du cycle de vie non seulement pour modifier la classe d'un objet, mais Ă©galement pour supprimer des objets plus anciens qu'un certain seuil.



Stockage des données sous forme de tableaux et de structures



En plus d'autres ensembles de donnĂ©es accessibles au public, BigQuery dispose d'un ensemble de donnĂ©es contenant des informations sur les tempĂȘtes cycloniques (ouragans, typhons, cyclones, etc.) provenant des services mĂ©tĂ©orologiques du monde entier. Les tempĂȘtes cycloniques peuvent durer jusqu'Ă  plusieurs semaines et leurs paramĂštres mĂ©tĂ©orologiques sont mesurĂ©s environ toutes les trois heures. Supposons que vous dĂ©cidiez de trouver dans cet ensemble de donnĂ©es toutes les tempĂȘtes qui se sont produites en 2018, la vitesse maximale du vent atteinte par chaque tempĂȘte, ainsi que l'heure et le lieu de la tempĂȘte lorsque cette vitesse maximale a Ă©tĂ© atteinte. La requĂȘte suivante rĂ©cupĂšre toutes ces informations de l'ensemble de donnĂ©es public:



SELECT
  sid, number, basin, name,
  ARRAY_AGG(STRUCT(iso_time, usa_latitude, usa_longitude, usa_wind) ORDER BY
usa_wind DESC LIMIT 1)[OFFSET(0)].*
FROM
  `bigquery-public-data`.noaa_hurricanes.hurricanes
WHERE
  season = '2018'
GROUP BY
  sid, number, basin, name
ORDER BY number ASC


La requĂȘte rĂ©cupĂšre l'identifiant de la tempĂȘte (Sid), ses saisons, son bassin et le nom de la tempĂȘte (si attribuĂ©), puis trouve un tableau d'observations effectuĂ©es pour cette tempĂȘte, en classant les observations par ordre dĂ©croissant de vitesse du vent et en choisissant la vitesse maximale pour chaque tempĂȘte. ... Les tempĂȘtes elles-mĂȘmes sont classĂ©es par numĂ©ro sĂ©quentiel. Le rĂ©sultat comprend 88 enregistrements et ressemble Ă  ceci:





La demande a pris 1,4 seconde et traitĂ© 41,7 Mo. La premiĂšre entrĂ©e dĂ©crit la tempĂȘte Bolaven, qui a atteint une vitesse maximale de 29 m / s le 2 janvier 2018 Ă  18h00 UTC.



Étant donnĂ© que les observations sont effectuĂ©es par plusieurs services mĂ©tĂ©orologiques, ces donnĂ©es peuvent ĂȘtre standardisĂ©es Ă  l'aide de champs imbriquĂ©s et stockĂ©es dans BigQuery, comme indiquĂ© ci-dessous:



CREATE OR REPLACE TABLE ch07.hurricanes_nested AS

SELECT sid, season, number, basin, name, iso_time, nature, usa_sshs,
    STRUCT(usa_latitude AS latitude, usa_longitude AS longitude, usa_wind AS
wind, usa_pressure AS pressure) AS usa,
    STRUCT(tokyo_latitude AS latitude, tokyo_longitude AS longitude,
tokyo_wind AS wind, tokyo_pressure AS pressure) AS tokyo,
    ... AS cma,
    ... AS hko,
    ... AS newdelhi,
    ... AS reunion,
    ... bom,
    ... AS wellington,
    ... nadi
FROM `bigquery-public-data`.noaa_hurricanes.hurricanes


Les requĂȘtes sur cette table ont le mĂȘme aspect que les requĂȘtes sur la table d'origine, mais avec un lĂ©ger changement dans les noms des colonnes (usa.latitude au lieu de usa_latitude):



SELECT
  sid, number, basin, name,
  ARRAY_AGG(STRUCT(iso_time, usa.latitude, usa.longitude, usa.wind) ORDER BY
usa.wind DESC LIMIT 1)[OFFSET(0)].*
FROM
  ch07.hurricanes_nested
WHERE
  season = '2018'
GROUP BY
  sid, number, basin, name
ORDER BY number ASC


Cette demande traite la mĂȘme quantitĂ© de donnĂ©es et s'exĂ©cute dans le mĂȘme laps de temps que l'original, en utilisant l'ensemble de donnĂ©es public. L'utilisation de champs (structures) imbriquĂ©s ne modifie pas la vitesse ou le coĂ»t de la requĂȘte, mais peut rendre la requĂȘte plus lisible. Comme il y a de nombreuses observations de la mĂȘme tempĂȘte au cours de sa durĂ©e, nous pouvons modifier le stockage pour adapter l'ensemble des observations pour chaque tempĂȘte dans un seul enregistrement:



CREATE OR REPLACE TABLE ch07.hurricanes_nested_track AS

SELECT sid, season, number, basin, name,
 ARRAY_AGG(
   STRUCT(
    iso_time,
    nature,
    usa_sshs,
    STRUCT(usa_latitude AS latitude, usa_longitude AS longitude, usa_wind AS
wind, usa_pressure AS pressure) AS usa,
    STRUCT(tokyo_latitude AS latitude, tokyo_longitude AS longitude,
      tokyo_wind AS wind, tokyo_pressure AS pressure) AS tokyo,
    ... AS cma,
    ... AS hko,
    ... AS newdelhi,
    ... AS reunion,
    ... bom,
    ... AS wellington,
    ... nadi
  ) ORDER BY iso_time ASC ) AS obs
FROM `bigquery-public-data`.noaa_hurricanes.hurricanes
GROUP BY sid, season, number, basin, name


Notez que nous stockons dĂ©sormais le sid, la saison et d'autres caractĂ©ristiques de la tempĂȘte sous forme de colonnes scalaires, car elles ne changent pas en fonction de sa durĂ©e.



Le reste des donnĂ©es, changeant Ă  chaque observation, est stockĂ© sous forme de tableau de structures. Voici Ă  quoi ressemble la requĂȘte pour la nouvelle table:



SELECT
  number, name, basin,
  (SELECT AS STRUCT iso_time, usa.latitude, usa.longitude, usa.wind
     FROM UNNEST(obs) ORDER BY usa.wind DESC LIMIT 1).*
FROM ch07.hurricanes_nested_track
WHERE season = '2018'
ORDER BY number ASC


Cette requĂȘte renverra le mĂȘme rĂ©sultat, mais cette fois, elle ne traitera que 14,7 Mo (une triple rĂ©duction des coĂ»ts) et se terminera en une seconde (une augmentation de 30% de la vitesse). Qu'est-ce qui a causĂ© cette amĂ©lioration des performances? Lorsque les donnĂ©es sont stockĂ©es sous forme de tableau, le nombre d'enregistrements dans la table diminue considĂ©rablement (de 682 000 Ă  14 000) 2, car il n'y a plus qu'un enregistrement par tempĂȘte, pas beaucoup d'enregistrements - un pour chaque observation. Ensuite, lorsque nous filtrons les lignes par saison, BigQuery peut supprimer de nombreux cas associĂ©s en mĂȘme temps, comme illustrĂ© dans la figure 1. 7.13.





Un autre avantage est qu'il n'est pas nĂ©cessaire de dupliquer les enregistrements de donnĂ©es lorsque des observations avec diffĂ©rents niveaux de dĂ©tail sont stockĂ©es dans la mĂȘme table. Une table peut stocker des donnĂ©es de changement de latitude et de longitude pour les tempĂȘtes et des donnĂ©es de haut niveau telles que les noms et la saison des tempĂȘtes. Et comme BigQuery stocke les donnĂ©es tabulaires dans des colonnes Ă  l'aide de la compression, vous pouvez interroger et traiter des donnĂ©es de haut niveau sans craindre le coĂ»t de l'utilisation de donnĂ©es dĂ©taillĂ©es - elles sont dĂ©sormais stockĂ©es sous forme de tableau distinct de valeurs pour chaque tempĂȘte.



Par exemple, pour connaĂźtre le nombre de tempĂȘtes par annĂ©e, vous ne pouvez interroger que les colonnes requises:



WITH hurricane_detail AS (
SELECT sid, season, number, basin, name,
 ARRAY_AGG(
  STRUCT(
    iso_time,
    nature,
    usa_sshs,
    STRUCT(usa_latitude AS latitude, usa_longitude AS longitude, usa_wind AS
wind, usa_pressure AS pressure) AS usa,
    STRUCT(tokyo_latitude AS latitude, tokyo_longitude AS longitude,
        tokyo_wind
AS wind, tokyo_pressure AS pressure) AS tokyo
  ) ORDER BY iso_time ASC ) AS obs
FROM `bigquery-public-data`.noaa_hurricanes.hurricanes
GROUP BY sid, season, number, basin, name
)
SELECT
  COUNT(sid) AS count_of_storms,
  season
FROM hurricane_detail
GROUP BY season
ORDER BY season DESC


La demande prĂ©cĂ©dente traitait 27 Mo, soit la moitiĂ© des 56 Mo qui devraient ĂȘtre traitĂ©s si les champs rĂ©pĂ©titifs imbriquĂ©s n'Ă©taient pas utilisĂ©s.



Les champs imbriquĂ©s n'amĂ©liorent pas les performances par eux-mĂȘmes, bien qu'ils puissent amĂ©liorer la lisibilitĂ© en effectuant une jointure Ă  d'autres tables associĂ©es. De plus, les champs rĂ©pĂ©titifs imbriquĂ©s sont extrĂȘmement utiles du point de vue des performances. Pensez Ă  utiliser des champs rĂ©pĂ©titifs imbriquĂ©s dans votre schĂ©ma, car ils peuvent considĂ©rablement augmenter la vitesse et rĂ©duire le coĂ»t du filtrage des requĂȘtes sur une colonne non imbriquĂ©e ou rĂ©pĂ©titive (dans notre cas, saison).



Le principal inconvĂ©nient des champs rĂ©pĂ©titifs imbriquĂ©s est la difficultĂ© d'implĂ©menter la diffusion en continu dans une telle table si les mises Ă  jour en continu impliquent l'ajout d'Ă©lĂ©ments Ă  des tableaux existants. C'est beaucoup plus difficile Ă  mettre en Ɠuvre que l'ajout de nouveaux enregistrements: vous devrez modifier un enregistrement existant - pour la table d'informations sur la tempĂȘte, c'est un inconvĂ©nient majeur, car de nouvelles observations y sont constamment ajoutĂ©es, et cela explique pourquoi cet ensemble de donnĂ©es public n'utilise pas de doublons imbriquĂ©s des champs.



Pratique de l'utilisation de tableaux



L'expérience a montré qu'il faut un peu de pratique pour utiliser avec succÚs des champs répétitifs imbriqués. L'exemple d'ensemble de données Google Analytics dans BigQuery est idéal à cette fin. Le moyen le plus simple d'identifier les données imbriquées dans un schéma consiste à rechercher le mot RECORD dans la colonne Type, qui correspond au type de données STRUCT, et le mot REPEATED dans la colonne Mode, comme indiqué ci-dessous:





Dans cet exemple, le champ TOTALS est STRUCT (mais pas répété) et le champ HITS est STRUCT et se répÚte. Cela a du sens, car Google Analytics suit les données de session des visiteurs au niveau d'agrégation (une valeur de session pour totals.hits) et au niveau de granularité (valeurs hit.time distinctes pour chaque page et images extraites de votre site) ... Le stockage des données à ces différents niveaux de détail sans duplication de visiteurId dans les enregistrements n'est possible qu'avec des tableaux. AprÚs avoir enregistré les données dans un format répétitif avec des tableaux, vous devez envisager de déployer ces données dans vos demandes à l'aide de UNNEST, par exemple:



SELECT DISTINCT
  visitId
  , totals.pageviews
  , totals.timeOnsite
  , trafficSource.source
  , device.browser
  , device.isMobile
  , h.page.pageTitle
FROM
  `bigquery-public-data`.google_analytics_sample.ga_sessions_20170801,
  UNNEST(hits) AS h
WHERE
  totals.timeOnSite IS NOT NULL AND h.page.pageTitle =
'Shopping Cart'
ORDER BY pageviews DESC
LIMIT 10
     ,   [1,2,3,4,5]   :
[1,
2
3
4
5]


Vous pouvez ensuite effectuer des opérations SQL normales telles que WHERE pour filtrer les appels sur les pages avec des titres tels que Panier. Essayez-le!



D'autre part, l'ensemble de donnĂ©es d'informations de commit public GitHub (bigquery-publicdata.githubrepos.commits) utilise un champ rĂ©pĂ©titif imbriquĂ© (reponame) pour stocker la liste des rĂ©fĂ©rentiels affectĂ©s par le commit. Il ne change pas au fil du temps et fournit des requĂȘtes plus rapides qui filtrent sur n'importe quel autre champ.



Stockage des données sous forme de types géographiques



L'ensemble de données public BigQuery contient un tableau des limites des zones de code postal américain (bigquery-public-data.utilityus.zipcodearea) et un autre tableau avec des polygones décrivant les limites des villes américaines (bigquery-publicdata.utilityus.uscitiesarea). Une colonne zipcodegeom est une chaßne, tandis qu'une colonne city_geom est un type géographique.



À partir de ces deux tableaux, vous pouvez obtenir une liste de tous les codes postaux pour Santa Fe au Nouveau-Mexique, comme indiquĂ© ci-dessous:



SELECT name, zipcode
FROM `bigquery-public-data`.utility_us.zipcode_area
JOIN `bigquery-public-data`.utility_us.us_cities_area
ON ST_INTERSECTS(ST_GeogFromText(zipcode_geom), city_geom)
WHERE name LIKE '%Santa Fe%'


Cette requĂȘte prend 51,9 secondes, traite 305,5 Mo de donnĂ©es et renvoie les rĂ©sultats suivants:





Pourquoi cette demande prend-elle autant de temps? Ce n'est pas à cause de l'opération STINTERSECTS, mais principalement parce que la fonction STGeogFromText doit évaluer les cellules S2 et construire le type GEOGRAPHY correspondant à chaque code postal.



Nous pouvons essayer de modifier la table des codes postaux en faisant cela au préalable et stocker la géométrie en tant que valeur GEOGRAPHY:



CREATE OR REPLACE TABLE ch07.zipcode_area AS
SELECT 
  * REPLACE(ST_GeogFromText(zipcode_geom) AS zipcode_geom)
FROM 
  `bigquery-public-data`.utility_us.zipcode_area


REPLACE (voir la requĂȘte prĂ©cĂ©dente) est un moyen pratique de remplacer une colonne d'une expression SELECT *.
Le nouvel ensemble de donnĂ©es a une taille de 131,8 Mo, ce qui est nettement plus grand que les 116,5 Mo du tableau d'origine. Cependant, les requĂȘtes sur cette table peuvent utiliser la couverture S2 et sont beaucoup plus rapides. Par exemple, la requĂȘte suivante prend 5,3 secondes (une augmentation de 10 fois la vitesse) et traite 320,8 Mo (une lĂ©gĂšre augmentation du coĂ»t lors de l'utilisation d'un plan tarifaire «à la demande»):



SELECT name, zipcode
FROM ch07.zipcode_area
JOIN `bigquery-public-data`.utility_us.us_cities_area
ON ST_INTERSECTS(zipcode_geom, city_geom)
WHERE name LIKE '%Santa Fe%'


Les avantages en termes de performances du stockage des donnĂ©es gĂ©ographiques dans une colonne GEOGRAPHY sont plus que convaincants. C'est pourquoi l'ensemble de donnĂ©es Utilityus est obsolĂšte (il est toujours disponible pour conserver les requĂȘtes dĂ©jĂ  Ă©crites) en vie. Nous vous recommandons d'utiliser la table bigquery-public-data.geousboundaries.uszip_codes, qui stocke les informations gĂ©ographiques dans une colonne GEOGRAPHY et est constamment mise Ă  jour.



»Plus de dĂ©tails sur le livre peuvent ĂȘtre trouvĂ©s sur le site de la maison d'Ă©dition

» Table des matiÚres

» Extrait



Pour Habitants une réduction de 25% sur le coupon - Google



Lors du paiement de la version papier du livre, un e-book est envoyé à l'e-mail.



All Articles