One place for hosting & domains

      Comprendre

      Comprendre les actions asynchrones de Redux avec Redux Thunk


      Introduction

      Par défaut, les actions de Redux sont expédiées de façon synchrone, ce qui pose un problème pour toute application non triviale qui doit communiquer avec une application externe ou effectuer des effets secondaires. Redux permet également au middleware qui se trouve au milieu d’une action d’être distribué et à l’action d’atteindre les réducteurs.

      Il existe deux bibliothèques de middleware très populaires qui prennent en charge les effets spéciaux et les actions asynchrones : Redux Thunk et Redux Saga. Cette publication vous emmène à la découverte de Redux Thunk.

      Thunk est un concept de programmation dans lequel une fonction est utilisée pour retarder l’évaluation/le calcul d’une opération.

      Redux Thunk est un middleware qui vous permet de faire un appel à l’action auprès des créateurs qui renvoie une fonction au lieu d’un objet d’action. Cette fonction reçoit la méthode de distribution du store. Elle permet donc d’envoyer des actions synchrones régulières dans le corps de la fonction une fois que les opérations asynchrones ont été terminées.

      Dans cet article vous allez apprendre à ajouter Redux Thunk et découvrir de quelle manière il peut s’adapter à une application hypothétique de Todo.

      Conditions préalables

      Cet article suppose que vous disposez de certaines connaissances de base sur React et Redux. Vous pouvez consulter cet article si vous débutez avec Redux.

      Ce tutoriel est construit autour d’une hypothétique application de Todo qui est supposée assurer le suivi des tâches à faire et des tâches accomplies. Nous présumons que create-react-app a été utilisée pour générer une nouvelle application React. Cependant, redux, react-redux et axios ont déjà été installés.

      Cet article ne vous donne pas d’informations plus détaillées sur la manière de créer une application de Todo de zéro. Nous la présentons ici comme un paramètre conceptuel pour mettre en avant Redux Thunk.

      Ajout de redux-thunk

      Tout d’abord, utilisez le terminal pour naviguer vers le répertoire de projets et installez le paquet redux-thunk dans votre projet :

      • npm install redux-thunk@2.3.0

      Remarque : Redux Thunk ne dispose que de 14 lignes de code. Consultez la source ici pour en savoir plus sur le fonctionnement en arrière-plan d’un middleware Redux.

      Maintenant, utilisez le middleware pour créer le store de votre application en utilisant applyMiddleware de Redux. Avec une application React intégrant redux et react-redux, votre fichier index.js devrait ressembler à ce qui suit :

      src/index.js

      import React from 'react';
      import ReactDOM from 'react-dom';
      import { Provider } from 'react-redux';
      import { createStore, applyMiddleware } from 'redux';
      import thunk from 'redux-thunk';
      import './index.css';
      import rootReducer from './reducers';
      import App from './App';
      import * as serviceWorker from './serviceWorker';
      
      // use applyMiddleware to add the thunk middleware to the store
      const store = createStore(rootReducer, applyMiddleware(thunk));
      
      ReactDOM.render(
        <Provider store={store}>
          <App />
        </Provider>,
        document.getElementById('root')
      );
      

      Maintenant, Redux Thunk a été importé et appliqué dans votre application.

      Utilisation de Redux Thunk dans un exemple d’application

      Redux Thunk est le plus couramment utilisé pour communiquer de manière asynchrone avec une application externe afin de récupérer ou de sauvegarder des données. Redux Thunk vous permet de facilement distribuer des actions qui suivent le cycle de vie d’une requête à une application externe.

      En règle générale, pour créer un nouvel élément de todo, il faut lancer une action pour indiquer qu’une création d’un élément todo a commencé. Ensuite, si l’élément todo est bien créé et renvoyé par le serveur externe, une autre action est distribuée avec le nouvel élément todo. Si une erreur survient et le serveur ne sauvegarde pas le todo, une action accompagnée d’une erreur risque d’être déclenchée.

      Voyons comment nous pourrions le faire avec Redux Thunk.

      Importez et distribuez l’action dans votre composant de conteneur :

      src/containers/AddTodo.js

      import { connect } from 'react-redux';
      import { addTodo } from '../actions';
      import NewTodo from '../components/NewTodo';
      
      const mapDispatchToProps = dispatch => {
        return {
          onAddTodo: todo => {
            dispatch(addTodo(todo));
          }
        };
      };
      
      export default connect(
        null,
        mapDispatchToProps
      )(NewTodo);
      

      L’action utilisera Axios pour envoyer une requête POST au terminal, au niveau de JSONPlaceholder (https://jsonplaceholder.typicode.com/todos) :

      src/actions/index.js

      import {
        ADD_TODO_SUCCESS,
        ADD_TODO_FAILURE,
        ADD_TODO_STARTED,
        DELETE_TODO
      } from './types';
      
      import axios from 'axios';
      
      export const addTodo = ({ title, userId }) => {
        return dispatch => {
          dispatch(addTodoStarted());
      
          axios
            .post(`https://jsonplaceholder.typicode.com/todos`, {
              title,
              userId,
              completed: false
            })
            .then(res => {
              dispatch(addTodoSuccess(res.data));
            })
            .catch(err => {
              dispatch(addTodoFailure(err.message));
            });
        };
      };
      
      const addTodoSuccess = todo => ({
        type: ADD_TODO_SUCCESS,
        payload: {
          ...todo
        }
      });
      
      const addTodoStarted = () => ({
        type: ADD_TODO_STARTED
      });
      
      const addTodoFailure = error => ({
        type: ADD_TODO_FAILURE,
        payload: {
          error
        }
      });
      

      Notez que le créateur d’action addTodo renvoie une fonction au lieu de l’objet d’action habituel. Cette fonction reçoit la méthode d’envoi du store.

      À l’intérieur du corps de la fonction, envoyez tout d’abord une action synchrone immédiate au store pour indiquer que vous avez commencé à enregistrer le todo avec l’application externe. Ensuite, vous devez envoyer la requête POST en elle-même au serveur, en utilisant Axios. Si le serveur vous envoie une réponse positive, vous distribuez une action synchrone probante avec les données reçues via la réponse. Mais, si la réponse est un échec, nous distribuons une action synchrone différente avec le message d’erreur.

      Lorsque vous utilisez une API externe, comme JSONPlaceholder dans le cas présent, il est possible qu’il y ait un retard au niveau du réseau. Cependant, si vous travaillez avec un serveur de backend local, il se peut que les réponses du réseau soient trop rapides pour pouvoir constater le retard de réseau qu’un utilisateur réel devrait subir. Vous pouvez donc ajouter un retard artificiel au cours du développement :

      src/actions/index.js

      // ...
      
      export const addTodo = ({ title, userId }) => {
        return dispatch => {
          dispatch(addTodoStarted());
      
          axios
            .post(ENDPOINT, {
              title,
              userId,
              completed: false
            })
            .then(res => {
              setTimeout(() => {
                dispatch(addTodoSuccess(res.data));
              }, 2500);
            })
            .catch(err => {
              dispatch(addTodoFailure(err.message));
            });
        };
      };
      
      // ...
      

      Pour tester les scénarios d’erreur, vous pouvez lancer une erreur manuellement :

      src/actions/index.js

      // ...
      
      export const addTodo = ({ title, userId }) => {
        return dispatch => {
          dispatch(addTodoStarted());
      
          axios
            .post(ENDPOINT, {
              title,
              userId,
              completed: false
            })
            .then(res => {
              throw new Error('addToDo error!');
              // dispatch(addTodoSuccess(res.data));
            })
            .catch(err => {
              dispatch(addTodoFailure(err.message));
            });
        };
      };
      
      // ...
      

      Pour compléter, voici un exemple de ce à quoi le réducteur de todo pourrait ressembler pour prendre en charge l’intégralité du cycle de vie de la requête :

      src/reducers/todosReducer.js

      import {
        ADD_TODO_SUCCESS,
        ADD_TODO_FAILURE,
        ADD_TODO_STARTED,
        DELETE_TODO
      } from '../actions/types';
      
      const initialState = {
        loading: false,
        todos: [],
        error: null
      };
      
      export default function todosReducer(state = initialState, action) {
        switch (action.type) {
          case ADD_TODO_STARTED:
            return {
              ...state,
              loading: true
            };
          case ADD_TODO_SUCCESS:
            return {
              ...state,
              loading: false,
              error: null,
              todos: [...state.todos, action.payload]
            };
          case ADD_TODO_FAILURE:
            return {
              ...state,
              loading: false,
              error: action.payload.error
            };
          default:
            return state;
        }
      }
      

      Découverte de getState

      Non seulement la méthode de distribution de l’état est reçue, mais la fonction renvoyée par un créateur d’action asynchrone avec Redux Thunk reçoit également la méthode getState du store pour pouvoir lire les valeurs réelles du store :

      src/actions/index.js

      export const addTodo = ({ title, userId }) => {
        return (dispatch, getState) => {
          dispatch(addTodoStarted());
      
          console.log('current state:', getState());
      
          // ...
        };
      };
      

      Avec ce qui précède, l’état actuel s’imprimera sur la console.

      Par exemple :

      {loading: true, todos: Array(1), error: null}
      

      Il peut s’avérer utile d’utiliser getState pour gérer les choses différemment en fonction de l’état actuel. Par exemple, si vous souhaitez limiter l’application à quatre éléments de todo à la fois, vous pouvez les renvoyer à partir de la fonction, si l’état contient déjà le nombre maximum d’éléments todo :

      src/actions/index.js

      export const addTodo = ({ title, userId }) => {
        return (dispatch, getState) => {
          const { todos } = getState();
      
          if (todos.length > 4) return;
      
          dispatch(addTodoStarted());
      
          // ...
        };
      };
      

      Compte tenu de ce qui précède, l’app sera limitée à quatre éléments de todo.

      Conclusion

      Au cours de ce tutoriel, vous avez appris à ajouter Redux Thunk à une application React pour pouvoir exécuter des actions de manière asynchrone. Ceci est utile si vous utilisez un store Redux et que vous vous appuyez sur des API externes.

      Si vous souhaitez en savoir plus sur React, consultez notre série Comment coder dans React.js ou consultez notre page thématique React pour des exercices et des projets de programmation.



      Source link

      Comprendre les hooks de cycle de vie Vue.js


      Introduction

      Les hooks de cycle de vie apparaissent sous la forme d’une fenêtre dans laquelle vous pouvez voir de quelle manière la bibliothèque que vous utilisez fonctionne en arrière-plan. Ils vous permettent de savoir à quel moment votre composant est créé, ajouté au DOM, mis à jour ou détruit.

      Ce schéma, tiré de la documentation officielle de Vue.js, représente le cycle de vie de l’instance Vue.js :

      Schéma du cycle de vie de Vue.js

      Cet article est une introduction aux hooks de création, de compilation, de mise à jour et de destruction.

      Comprendre les hooks de création (initialisation)

      Les hooks de création sont les tous premiers à s’exécuter dans votre composant. Ils vous permettent de réaliser des actions avant même que votre composant n’ait été ajouté au DOM. Contrairement aux autres, les hooks de création sont également exécutés lorsque le rendu est généré côté serveur.

      Vous pouvez les utiliser pour configurer certains éléments dans votre composant, que le rendu soit généré côté client ou côté serveur.

      À l’intérieur des hooks de création, vous n’aurez pas accès au DOM ou à l’élément de compilation cible (this.$el).

      beforeCreate

      Le hook beforeCreate s’exécute au moment même de l’initalisation de votre composant. data n’a pas été activé et les events n’ont pas encore été configurés :

      ExampleComponent.vue

      <script>
      export default {
        beforeCreate() {
          console.log('At this point, events and lifecycle have been initialized.')
        }
      }
      </script>
      

      Dans cet exemple, lorsque le hook beforeCreate est exécuté, ce fragment de code consigne le message suivant : Initialisation des événements et du cycle de vie.

      created

      Le hook created vous permet d’accéder aux data et events qui sont actifs. La compilation ou le rendu des modèles et du DOM virtuel n’ont pas encore été déclenchés :

      ExampleComponent.vue

      <template>
        <div ref="example-element">{{ propertyComputed }}</div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            property: 'Example property.'
          }
        },
      
        computed: {
          propertyComputed() {
            return this.property
          }
        },
      
        created() {
          console.log('At this point, this.property is now reactive and propertyComputed will update.')
          this.property = 'Example property updated.'
        }
      }
      </script>
      

      Dans cet exemple, le fragment de code consigne que property est une Example property. Lorsque le hook created est exécuté, le message suivant est enregistré : this.property est maintenant réactive et propertyComputed sera mise à jour. Ensuite, la valeur sous property est remplacée par Example property updated.

      Plus tard dans le cycle de vie, {{propertyComputed }} indiquera Example property updated au lieu de Example property.

      Au cours de cette étape, vous avez examiné quelques exemples de hooks de création. Vous êtes maintenant prêt à passer à la prochaine étape du cycle de vie, la compilation de hooks.

      Comprendre les hooks de compilation (insertion DOM)

      Les hooks de compilation sont ceux qui sont généralement les plus utilisés. Ils vous permettent d’accéder à votre composant immédiatement avant et après avoir généré le premier rendu. Cependant, ils ne sont pas exécutés lors du rendu côté serveur.

      Vous pouvez utiliser les hooks de compilation pour accéder ou modifier le DOM de votre composant immédiatement avant ou après avoir généré le rendu initial.

      N’utilisez pas de hooks de compilation pour récupérer des données sur votre composant lors de son initialisation.

      Remarque : pour cela, utilisez plutôt created (ou created et activated pour les composants keep-alive), surtout si vous avez besoin de ces données pour le rendu côté serveur.

      beforeMount

      Le hook beforeMount s’exécute juste avant l’occurrence du rendu initial et une fois que les fonctions du modèle ou du rendu aient été compilées :

      ExampleComponent.vue

      <script>
      export default {
        beforeMount() {
          console.log(`At this point, vm.$el has not been created yet.`)
        }
      }
      </script>
      

      Dans cet exemple, lorsque le hook beforeMount est exécuté, ce fragment de code enregistrera le message suivant : vm.$el n'a pas encore été créé.

      mounted

      Le hook mounted vous permet d’avoir un total accès au composant réactif, aux modèles et au DOM rendu (via this.$el).

      Utilisez mounted pour modifier le DOM, notamment lors de l’intégration de bibliothèque hors Vue :

      ExampleComponent.vue

      <template>
        <div ref="example-element">Example component.</div>
      </template>
      
      <script>
      export default {
        mounted() {
          console.log(`At this point, vm.$el has been created and el has been replaced.`);
          console.log(this.$el.textContent) // Example component.
        }
      }
      </script>
      

      Dans notre exemple, lorsque le hook mounted est exécuté, ce fragment de code consigne le message suivant : Crée vm.$el pour remplacer el. Le message Ceci est un exemple de texte (this.$el.textContent) sera également enregistré.

      Au cours de cette section, vous avez exploré les cas d’utilisation de hooks de compilation. À l’étape suivante, vous allez aborder quelques exemples de hooks de mise à jour.

      Comprendre les hooks de mise à jour (Diff et Re-render)

      Les Updating hooks se déclenchnt à chaque fois qu’une propriété réactive utilisée par votre composant change ou que quelque chose d’autre vous pousse à le re-render. Ils vous permettent de vous hooker au cycle watch-compute-render de votre composant.

      Vous pouvez utiliser les hooks de mise à jour pour savoir à quel moment le rendu du composant est de nouveau déclenché, éventuellement en vue d’un débogage ou d’un profilage.

      N’utilisez pas la mise à jour de hooks pour déterminer à quel moment une propriété réactive de votre composant change. Utilisez plutôt computed properties ou watchers.

      beforeUpdate

      Le hook beforeUpdate s’exécute une fois que les données de votre composant changent et que le cycle de mise à jour commence, juste avant que le DOM n’ait été patché et n’ait généré un re-render.

      Utilisez beforeUpdate pour consulter le nouvel état de toute donnée réactive de votre composant avant que le rendu soit effectivement généré :

      ExampleComponent.vue

      <template>
        <div ref="example-element">{{counter}}</div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            counter: 0
          }
        },
      
        created() {
          setInterval(() => {
            this.counter++
          }, 1000)
        },
      
        beforeUpdate() {
          console.log(`At this point, Virtual DOM has not re-rendered or patched yet.`)
          // Logs the counter value every second, before the DOM updates.
          console.log(this.counter)
        }
      }
      </script>
      

      Tout d’abord, sous counter, ce fragment de code enregistrera 0. Lorsque le hook created est exécuté, la valeur du counter incrémentera toutes les 1 000 ms. Lorsque le hook beforeUpdate est exécuté, ce fragment de code enregistrera le message suivant : DOM virtuel pas encore été rendu ou patché. et un numéro sera enregistré sous counter.

      updated

      L’exécution du hook updated se fait à chaque fois que les données concernant votre composant sont modifiées et que le DOM déclenche un re-render.

      Utilisez updated pour accéder au DOM une fois qu’une propriété ait été modifiée :

      ExampleComponent.vue

      <template>
        <div ref="example-element">{{counter}}</div>
      </template>
      
      <script>
      export default {
        data() {
          return {
            counter: 0
          }
        },
      
        created() {
          setInterval(() => {
            this.counter++
          }, 1000)
        },
      
        updated() {
          console.log(`At this point, Virtual DOM has re-rendered and patched.`)
          // Fired every second, should always be true
          console.log(+this.$refs['example-element'].textContent === this.counter)
        }
      }
      </script>
      

      Tout d’abord, sous counter, ce fragment de code enregistrera 0. Lorsque le hook created est exécuté, la valeur du counter incrémentera toutes les 1 000 ms. Lorsque le hook updated est exécuté, ce fragment de code consigne le message suivant : Nouveau rendu et patch du DOM virtuel. Et, étant donné que la valeur du rendu est égale à la valeur actuelle, la valeur booléenne de true est consignée.

      Maintenant que vous en savez davantage sur l’utilisation des hooks de mise à jour, nous pouvons aborder les hooks de destruction.

      Comprendre les hooks de destruction (Démontage)

      Les hooks de destruction vous permettent d’effectuer des actions lorsque votre composant est détruit. Vous pouvez par exemple procéder à son nettoyage ou à l’envoi d’analyses. Ils se déclenchent au moment où votre composant est détruit et supprimé du DOM.

      beforeDestroy

      Le déclenchement de beforeDestroy se fait juste avant le démontage. Votre composant sera toujours présent et totalement fonctionnel.

      Utilisez beforeDestroy pour nettoyer des événements ou des abonnements réactifs :

      ExampleComponent.vue

      <script>
      export default {
        data() {
          return {
            exampleLeakyProperty: 'This represents a property that will leak memory if not cleaned up.'
          }
        },
      
        beforeDestroy() {
          console.log(`At this point, watchers, child components, and event listeners have not been teared down yet.`)
          // Perform the teardown procedure for exampleLeakyProperty.
          // (In this case, effectively nothing)
          this.exampleLeakyProperty = null
          delete this.exampleLeakyProperty
        }
      }
      </script>
      

      Ce fragment de code consignera tout d’abord exampleLeakyProperty. Lorsque le hook beforeDestroy est exécuté, ce fragment de code enregistrera le message suivant : Les observateurs, composants enfants et écouteurs d'événements n'ont pas encore été éliminés. Ensuite, exampleLeakyProperty est supprimé.

      destroyed

      Une fois que vous aurez atteint votre hooker destroyed, il ne vous restera pratiquement plus rien à faire sur votre composant. Tout ce qui y était rattaché a été détruit.

      Utilisez destroyed pour procéder à un nettoyage de dernière minute ou signaler à un serveur distant que le composant a été détruit :

      ExampleComponent.vue

      <script>
      import ExampleAnalyticsService from './example-analytics-service'
      
      export default {
        destroyed() {
          console.log(`At this point, watchers, child components, and event listeners have been torn down.`)
          console.log(this)
          ExampleAnalyticsService.informService('Component destroyed.')
        }
      }
      </script>
      

      Dans un premier temps, ce fragment de code importera ExampleAnalyticsService. Lorsque le hook beforeDestroy est exécuté, ce fragment de code consignera le message suivant : Supprime les observateurs, composants enfant et écouteurs d'événements. Ce qui reste du composant sera consigné dans la console et ExampleAnalyticsService transmettra le message suivant :Détruit.

      Voilà, vous êtes arrivé à la fin votre révision générale sur les hooks de cycle de vie Vue.js.

      Autres hooks

      Il existe deux autres hooks : activated et deactivated. Ils sont dédiés aux composants keep-alive, un sujet qui n’entre pas dans le cadre de cet article.

      Il vous suffit de savoir qu’ils vous permettent de détecter à quel moment un composant enveloppé dans une balise <keep-alive></keep-alive> est activé ou désactivé. Vous pouvez les utiliser pour récupérer les données de votre composant ou gérer les changements d’état, car ils se comportent effectivement comme created et beforeDestroy sans avoir à reconstruire un composant dans son intégralité.

      Conclusion

      Dans cet article, vous avez abordé les différents hooks de cycle de vie disponibles dans le cycle de vie d’une instance Vue.js. Vous avez découvert différents cas d’utilisation de hooks de création, de compilation, de mise à jour et de destruction.

      Si vous souhaitez en savoir plus sur Vue.js, veuillez consulter notre page thématique Vue.js dans laquelle vous trouverez des exercices et des projets de programmation.



      Source link

      Comprendre les bases de données relationnelles


      Introduction

      Les systèmes de gestion des bases de données (SGDB ou DBMS en anglais) sont des programmes informatiques qui permettent aux utilisateurs d’interagir avec une base de données. Un SGDB permet aux utilisateurs de contrôler l’accès à une base de données, d’écrire des données, d’exécuter des requêtes et d’effectuer toute autre tâche liée à la gestion de base de données.

      Pour effectuer l’une de ces tâches, cependant, le SGDB doit avoir une sorte de modèle sous-jacent qui définit la manière dont les données sont organisées. Le modèle relationnel est une approche d’organisation des données qui ont trouvé un large usage dans le logiciel de base de données depuis sa conception initiale à la fin des années 1960, à tel point que, à partir de ce texte, quatre des cinq SGDB les plus populaires sont relationnels.

      Cet article conceptuel décrit l’historique du modèle relationnel, la manière dont les bases de données relationnelles organisent les données, et leur utilisation aujourd’hui.

      Histoire du modèle relationnel

      Les bases de données sont des groupes d’informations ou de données modélisés de manière logique**. Toute collecte de données est une base de données, quel que soit la manière dont elle est stockée ou l’endroit où elle est stockée. Même un classeur de fichiers contenant des informations sur les salaires est une base de données, tout comme une pile de formulaires de patients d’un hôpital ou la collecte d’informations sur les clients d’une entreprise répartis dans plusieurs endroits. Avant que le stockage et la gestion des données à l’aide d’ordinateurs ne soit une pratique courante, les bases de données physiques comme celles-ci étaient les seules dont disposaient les organisations gouvernementales et commerciales qui avaient besoin de stocker des informations.

      Vers le milieu du XXe siècle, les développements en informatique ont conduit à la mise au point de machines plus puissantes, ainsi qu’à une plus grande capacité de stockage local et externe. Ces progrès ont conduit les informaticiens à commencer à reconnaître le potentiel de ces machines pour stocker et gérer des quantités de données toujours plus importantes.

      Cependant, il n’existait pas de théories sur la manière dont les ordinateurs pouvaient organiser les données de manière logique et significative. C’est une chose de stocker des données non triées sur une machine, mais il est beaucoup plus compliqué de concevoir des systèmes qui vous permettent d’ajouter, récupérer, trier et gérer ces données d’une manière cohérente et pratique. La nécessité d’un cadre logique pour stocker et organiser les données a conduit à un certain nombre de propositions d’utilisation des ordinateurs pour la gestion des données.

      L’un des premiers modèles de base de données était le modèle hiérarchique, dans lequel les données sont organisées dans une structure arborescente ressemblant semblables aux systèmes de fichiers modernes. L’exemple suivant montre à quoi pourrait ressembler la disposition d’une partie d’une base de données hiérarchique utilisée pour classer les animaux : :

      Exemple Base de données hiérarchiques : catégorisation des animaux

      Le modèle hiérarchique a été largement appliqué dans les systèmes de gestion de base de données, mais il s’est également avéré peu flexible. Dans ce modèle, même si les enregistrements individuels peuvent avoir plusieurs enregistrements “enfant”, chaque enregistrement ne peut avoir qu’un seul “parent” dans la hiérarchie. Pour cette raison, ces bases de données hiérarchiques antérieures se limitaient à représenter uniquement des relations “”un à un” et “un à plusieurs” Cette absence de relations “de plusieurs à plusieurs”  pourrait entraîner des problèmes lorsque vous travaillez avec des points de données que vous souhaitez associer à plus d’un parent.

      À la fin des années 1960, Edgar F. Codd, un informaticien chez IBM, a mis au point le modèle relationnel de gestion de base de données. Le modèle relationnel de Codd a permis à des enregistrements individuels d’être associés à plus d’une table, permettant ainsi des relations “de plusieurs à plusieurs” entre les points de données en plus des relations “d’un à plusieurs”.  Cela a permis une plus grande flexibilité que d’autres modèles existants en ce qui concerne la conception des structures de base de données, ce qui signifie que les systèmes de gestion de bases de données relationnelles (SGBDR) pouvaient répondre à un éventail beaucoup plus large de besoins commerciaux.

      Codd a proposé un langage pour gérer les données relationnelles, connu sous le nom d’Alpha, qui a influencé le développement de langages de base de données ultérieurs. Deux des collègues de Codd chez IBM, Donald Chamberlin et Raymond Boyce, ont créé un tel langage inspirée d’Alpha. Ils ont appelé leur langue SEQUEL, anagramme de   S tructured  E nglish  Que ry  L anguage, mais en raison d’une marque existante ils ont raccourci le nom de leur langage à SQL (appelé de manière plus formelle Structured Query Language).

      En raison de contraintes matérielles, les premières bases de données relationnelles étaient excessivement lentes, et il a fallu un certain temps avant que la technologie ne se généralise. Mais au milieu des années 1980, le modèle relationnel de Codd a été mis en œuvre dans un certain nombre de produits de gestion de base de données commerciales d’IBM et de ses concurrents. Ces entreprises ont également suivi l’initiative d’IBM en développant et en mettant en œuvre leurs propres dialectes de SQL. En 1987, l’American National Standards Institute et l’International Organization for Standardization avaient tous deux ratifié et publié des normes pour SQL, consolidant ainsi son statut de langage accepté pour la gestion des SGBDR.

      L’utilisation du modèle relationnel dans plusieurs industries a conduit à sa reconnaissance en tant que modèle standard de gestion des données. Même avec l’essor de différentes bases de données NoSQL ces dernières années, les bases de données relationnelles restent les outils dominants pour le stockage et l’organisation des données.

      Maintenant que vous avez une compréhension générale de l’histoire du modèle relationnel, examinons de plus près la manière dont le modèle organise les données.

      Les éléments les plus fondamentaux du modèle relationnel sont les relations que les utilisateurs et les SGBDR modernes reconnaissent comme tableaux. Une relation est un ensemble de tuples, ou de lignes dans une table, avec chaque tuple partageant un ensemble d’attributs, ou colonnes :

      Exemple de diagramme indiquant comment les relations, les tuples et les attributs sont liés les uns aux autres

      Une colonne est la plus petite structure organisationnelle d’une base de données relationnelle, et représente les différentes facettes qui définissent les enregistrements de la table. D’où leur nom plus formel, les attributs. Vous pouvez penser à chaque tuple comme une instance unique de n’importe quel type de personnes, objets, événements ou associations que la table contient. Ces instances peuvent être des éléments comme les employés d’une entreprise, les ventes d’une entreprise en ligne ou les résultats de test en laboratoire. Par exemple, dans une table contenant les enregistrements des enseignants d’une école, les tuples peuvent avoir des attributs comme name, subjects, start_date, etc.

      Lorsque vous créez des colonnes, vous spécifiez un type de données qui dicte le type d’entrées autorisées dans cette colonne. Les SGBDR mettent souvent en œuvre leurs propres types de données uniques, qui peuvent ne pas être directement interchangeables avec des types de données similaires dans d’autres systèmes. Les types de données les plus courants comprennent les dates, les chaînes de caractères, les entiers et les Booléens.

      Dans le modèle relationnel, chaque table contient au moins une colonne qui peut être utilisée pour identifier de manière unique chaque ligne, appelée clé primaire. C’est important, car cela signifie que les utilisateurs n’ont pas à savoir où leurs données sont physiquement stockées sur une machine, au lieu de cela, leur SGBD peut suivre chaque enregistrement et les renvoyer sur une base ad hoc. Cela signifie que les enregistrements n’ont pas d’ordre logique défini, et que les utilisateurs ont la possibilité de renvoyer leurs données dans n’importe quel ordre ou par les filtres qu’ils souhaitent.

      Si vous souhaitez associer deux tables l’une à l’autre, vous pouvez le faire avec une clé étrangère. Une clé étrangère est essentiellement une copie de la clé primaire d’une table (la table “parent”) insérée dans une colonne d’une autre table (l’“enfant”). L’exemple suivant met en évidence la relation entre deux tableaux, l’un utilisé pour enregistrer les informations relatives aux employés d’une entreprise et l’autre utilisée pour suivre les ventes de l’entreprise. Dans cet exemple, la clé principale du tableau EMPLOYEES est utilisée comme clé étrangère du tableau SALES :

      Diagramme illustrant comment la clé principale du tableau de EMPLOYEE agit en tant que clé étrangère du tableau SALES

      Si vous essayez d’ajouter un enregistrement au tableau enfant et que la valeur saisie dans la colonne de clé étrangère n’existe pas dans la clé primaire du tableau parent, l’instruction d’insertion sera invalide. Cela aide à maintenir l’intégrité au niveau des relations, car les lignes des deux tableaux seront toujours correctement reliées.

      Les éléments structurels du modèle relationnel aident à conserver les données stockées de manière organisée, mais la conservation des données n’est utile que si vous pouvez les récupérer. Pour récupérer des informations d’un SGBDR, vous pouvez émettre une query ou une requête structurée d’un ensemble d’informations. Comme mentionné précédemment, la plupart des bases de données relationnelles utilisent SQL pour gérer et interroger les données. SQL vous permet de filtrer et de manipuler les résultats de requête avec une variété de clauses, de prédicats et d’expressions, vous donnant un contrôle précis sur les données qui apparaîtront dans l’ensemble de résultats.

      Avantages et limitations des bases de données relationnelles

      En tenant compte de la structure organisationnelle sous-jacente des bases de données relationnelles, examinons quelques-uns de leurs avantages et de leurs inconvénients.

      Aujourd’hui, tant SQL que les bases de données qui l’implémentent s’écartent du modèle relationnel de Codd de plusieurs façons. Par exemple, le modèle de Codd dicte que chaque ligne d’une table doit être unique tandis que, pour des raisons pratiques, la plupart des bases de données relationnelles modernes permettent de dupliquer les lignes. Certaines personnes ne considèrent pas les bases de données SQL comme de véritables bases de données relationnelles si elles ne respectent pas chacune des spécifications du modèle relationnel de Codd. En termes pratiques, cependant, tout SGBD qui utilise SQL et qui adhère au moins en partie au modèle relationnel est susceptible d’être appelé un système de gestion de base de données relationnelles.

      Bien que les bases de données relationnelles aient rapidement gagné en popularité, certaines des lacunes du modèle relationnel ont commencé à apparaître lorsque les données prenaient de la valeur et que les entreprises ont commencé à en stocker davantage. La scalabilité horizontale, ou scaling out, est la pratique qui consiste à ajouter plus de machines à une pile existante afin de répartir la charge et de permettre un traffic plus important et un traitement plus rapide. Cette opération est souvent opposée à la mise à la scalabilité verticale qui implique la mise à niveau du matériel d’un serveur existant, généralement en ajoutant plus de RAM ou de CPU.

      La raison pour laquelle il est difficile de faire évoluer une base de données relationnelle horizontalement est liée au fait que le modèle relationnel est conçu pour assurer la cohérence, ce qui signifie que les clients qui interrogent la même base de données récupèrent toujours les mêmes données. Si vous devez faire évoluer une base de données relationnelle horizontalement sur plusieurs machines, il devient difficile d’en garantir la cohérence car les clients peuvent parfois écrire des données sur un nœud, sans le faire sur les autres. Il y aurait probablement un délai entre l’écriture initiale et le moment où les autres nœuds sont mis à jour pour refléter les changements, ce qui entraînerait des incohérences entre eux.

      Une autre limitation présentée par les SGDBR est que le modèle relationnel a été conçu pour gérer des données structurées, ou des données qui s’alignent avec un type de données prédéfini ou qui sont au moins organisées d’une manière prédéterminée, ce qui les rend facilement triables et consultables. Toutefois, avec le développement de l’informatique personnelle et l’essor d’Internet au début des années 1990, les données non structurées — telles que les messages électroniques, les photos, les vidéos, etc. — sont devenues plus fréquentes.

      Rien de cela ne veut dire que les bases de données relationnelles ne sont pas utiles. Au contraire, le modèle relationnel est toujours le cadre dominant de la gestion des données après plus de 40 ans. Leur prévalence et leur longévité signifient que les bases de données relationnelles sont une technologie mature, qui est en soi l’un de leurs avantages majeurs. Il existe de nombreuses applications conçues pour fonctionner avec le modèle relationnel, ainsi que de nombreux administrateurs de base de données de carrière qui sont des experts en matière de bases de données relationnelles. Il existe également un large éventail de ressources disponibles sur papier et en ligne pour ceux qui souhaitent se lancer dans les bases de données relationnelles.

      Un autre avantage des bases de données relationnelles est que presque tous les SGBDR prennent en charge les transactions. Une transaction consiste en une ou plusieurs des instructions SQL individuelles exécutées en séquence comme une seule unité de travail. Les transactions présentent une approche de type tout-ou rien, ce qui signifie que chaque instruction SQL de la transaction doit être valide ; sinon, la transaction entière échouera. Ceci est très utile pour garantir l’intégrité des données lors de modifications de plusieurs lignes ou tableaux.

      Enfin, les bases de données relationnelles sont extrêmement flexibles. Elles ont été utilisées pour construire une grande variété d’applications différentes, et continuent de fonctionner efficacement même avec de très grandes quantités de données. SQL est également extrêmement puissant, vous permettant d’ajouter et de modifier des données au vol, ainsi que de modifier la structure des schémas et des tableaux de base de données sans incidence sur les données existantes.

      Conclusion

      Grâce à leur flexibilité et à leur conception pour l’intégrité des données, les bases de données relationnelles sont toujours le principal moyen de gérer et de stocker les données plus de cinquante ans après leur conception. Même avec l’essor de diverses bases de données NoSQL ces dernières années, la compréhension du modèle relationnel et de la manière de travailler avec les SGBDR sont la clé pour tous ceux qui veulent construire des applications qui exploitent la puissance des données.

      Pour en savoir plus sur quelques SGBDR open source populaires, nous vous encourageons à consulter notre comparaison de différentes bases de données SQL relationnelles open-source. Si vous souhaitez en savoir plus sur les bases de données en général, nous vous encourageons à consulter notre bibliothèque complète de contenus liés aux bases de données.



      Source link